when compiling my program with GCC I get the following warning:
format ‘%d’ expects type ‘int’, but argument 2 has type ‘long unsigned int
Now just by playing around I realize %lo fixes the warning. However I don't really understand what I am doing.
Is there a naming convention to get the short form of a type? For example, int is %d, why??
Thanks!
Description. Unsigned long variables are extended size variables for number storage, and store 32 bits (4 bytes). Unlike standard longs unsigned longs won't store negative numbers, making their range from 0 to 4,294,967,295 (2^32 - 1).
Maximum value of unsigned short int in C++ It is the smallest (16 bit) integer data type in C++. Some properties of the unsigned short int data type are: Being an unsigned data type, it can store only positive values. Takes a size of 16 bits.
%u. It is used to print the unsigned integer value where the unsigned integer means that the variable can hold only positive value.
Printing short, long, long long, and unsigned Types To print an unsigned int number, use the %u notation. To print a long value, use the %ld format specifier. You can use the l prefix for x and o, too. So you would use %lx to print a long integer in hexadecimal format and %lo to print in octal format.
long unsigned int = unsigned long
You use %lu
to print those.
And similarly, %llu
is for unsigned long long
.
%d - int
%u - unsigned
%ld - long
%lld - long long
%lu - unsigned long
%llu - unsigned long long
The definition of int, long, etc are specific to the target. If the size of int and long match then a
printf("%d",var);
wont complain, but if long is say 64 bits and int is 32 bits as an example, then you will get the warning/error you describe. One of two solutions:
printf("%ld",var);
or
printf("%d",(int)var);
For the latter of course you have to insure that the compiler associates int with the %d size, if you get yet another warning then adjust accordingly.
EDIT:
The compiler is trying to help you out, by worrying about C library stuff which is not really the business of the compiler. printf() uses a variable number of arguments, which hopefully you properly matched to your format string. When printf sees a %d on say a 32 bit system it likely will only grab the next 32 bit argument. But if you had put a 64 bit integer in as a parameter it may grab one half of that integer, and use the other half as the next item in the format string. For example
unsigned long ul;
float f;
f=3.4;
ul=0x3F9DF3B612345678;
...
printf("%X %f\n",ul,f);
Depending on your system, endianess, etc, a 32 bit system you should not at all be surprised if the above code produced this output:
12345678 1.234000
because that is what you told it to to. you told it to take the lower 32 bits of ul and print that as hex (%X) and the upper 32 bits of ul and print that as float (%f) and putting f in the function call was a waste you didnt provide any formatting to use the floating point value.
Now depending on the compiler on the target system on a particular day you may have the above code work as desired, take a system/compiler where unsigned long is interpreted as a 32 bit and %X is interpreted as 32 bit, then you get a warning about the 64 bit assignment but the printf makes a little bit more sense.
Because of this pain, compilers like gcc bother to try to make your life better by assuming that when you use a function called printf() you are using the standard C one and they parse through your format string looking for these types of common mistakes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With