Thread: strange error while adding a long to char

  1. #1
    Registered User
    Join Date
    Mar 2016
    Posts
    13

    strange error while adding a long to char

    Hello,

    I am writing a program where I have to take a string and add an input number(key) to each element of the string thus creating a sort of cipher. I have the line that does the addition to each element as

    Code:
    for(int i = 0; i < strlen(input); i++)
        {
            printf("%c", input[i] + (int)((key + 26) % 26));
        }
    This works as long as I have (int) type cast as shown above. But the function that implements the above code accepts the key as a long to accommodate for bigger integers. so if I just do not typecast to int and just do

    Code:
    for(int i = 0; i < strlen(input); i++)
        {
            printf("%c", input[i] + ((key + 26) % 26));
        }
    the compiler throws an error saying

    error: format specifies type 'int' but the argument has type 'long' [-Werror,-Wformat]
    [I] printf("%c", input + ((key + 26) % 26));

    I do not follow:

    1) Why I have to force the int typecast while a long is just an int with higher range.

    2) Why does the error say that my format specifies int while I am clearly specifying %c and not %d?
    Last edited by livin4th; 04-22-2019 at 11:31 AM.

  2. #2
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    1) Because the compiler warns you when you use the incorrect type in the printf format, and you have told the compiler to treat all warnings as errors. Also, a variable argument list has no set type for its arguments, so the compiler doesn't really know to cast that long to an int. So it ends up passing a long to printf, but printf tries to read an int. In systems where long is larger than int, that could be a problem.

    2) Character literals in C are of type int, as to why... probably to make the code easier to manage on the processor level.
    Devoted my life to programming...

  3. #3
    Registered User
    Join Date
    Apr 2019
    Posts
    62
    Quote Originally Posted by livin4th View Post
    But the function that implements the above code accepts the key as a long to accommodate for bigger integers. so if I just do not typecast to int and just do

    Code:
    for(int i = 0; i < strlen(input); i++)
        {
            printf("%c", input[i] + ((key + 26) % 26));
        }
    Why is key a long if you %26? Only the first 5 bits of key matter here.

    The issue here is that C must make all the terms in an expression agree on a type. If you do 1.0 + 1, it'll promote 1 to a double and the result will be a double. Here, the largest term is key, which is apparently a long. C will promote input[i] to a long, as well as the two integer literals. The result of the expression would be a long, but the specification in the format string is asking for a char, so you're getting an error.

    Confusingly, another promotion is taking place. When you pass any argument to a variadic function (like printf, that can take any number and type of arguments after the format string), it converts chars to ints. So if you have char a and do printf("%c", a), a is first converted to an int.

    Quote Originally Posted by GReaper View Post
    2) Character literals in C are of type int, as to why... probably to make the code easier to manage on the processor level.
    Even if character literals were chars, it would be promoted to int, unsigned or long as soon as you tried to use any operators on it. Even adding two char variables will promote to int, or taking the bitwise inverse of a char.

  4. #4
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Imagine %c is a door big enough to fit a wheel barrow 80cm wide.

    When you use "key", your compiler says, "well... that is 160cm wide [because it is of type "long"], so we'll put the result of this little calculation into one that big".

    You then go to wheel it into an 80cm door and you get the warning... As you should...


    When you use the cast, what you are saying is - When you get the output of that little calculation, just use a 80cm wheel barrow for the result, I know what I am doing.
    Fact - Beethoven wrote his first symphony in C

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Strange error with char array initialisation size
    By TheFallen018 in forum C Programming
    Replies: 1
    Last Post: 05-22-2018, 07:52 AM
  2. Adding two long together
    By crimson-med in forum C Programming
    Replies: 11
    Last Post: 12-10-2015, 07:24 PM
  3. how do I convert a long long int into a char array?
    By Once-ler in forum C Programming
    Replies: 15
    Last Post: 02-22-2013, 01:46 PM
  4. How to convert char array of 64 bytes to long long int
    By pkumarn in forum C Programming
    Replies: 19
    Last Post: 03-06-2012, 02:23 AM
  5. Adding int to long long
    By cybernike in forum C++ Programming
    Replies: 2
    Last Post: 12-18-2008, 11:03 PM

Tags for this Thread