Can printf lead to undefined behavior?

int main() { unsigned int i = 12; printf("%lu", i); // This yields a compiler warning } 

On a 32-bit platform, using printf with int using %lu leads to garbage?

+5
c ++ c
Apr 25 '14 at 7:50
source share
3 answers

Only the "32-bit platform" operator does not mean that int and long have both 32 bits and their copies unsigned .

So yes, indeed, this can happen if the unsingned long , for which %lu done, is longer than the unsigned int .

But even if the lengths are equal, the types are incompatible, so formally this behavior is undefined.

+8
Apr 25 '14 at 7:52
source share

If the required type and this type are incompatible, you have undefined behavior. It is completely legal for the compiler to pass information of type with a value when passing vararg and use it in va_arg (although I don’t know a single one that does, probably for historical reasons).

As for the practical effects in your particular case, "%lu" expects a long absence. The only other type that is compatible, and then only if the actual value is long non-negative. Passing it int is undefined although it might work. (On most 32-bit platforms, int and long have the same size and presentation.)

+4
Apr 25 '14 at 8:03
source share

Honestly, I do not understand why you should use% lu instead of% u, since you are working with int.

% lu should be used (in its most basic explanation) for unsigned long.

Most likely, it will print garbage if your compiler uses (and, of course, in 99% of cases) different storage sizes for int and long.

For example, according to the C standard, an unsigned int has a storage size of “At least 16 bits in size,” while an unsigned long has “At least 32 bits in size”.

Now let's take as an example 16 bits for int and 32 bits in length and let's look at an atypical example where the memory is all reset at the moment the program starts.

The value 12 is represented in memory as:

00000000 00001100

and if you type with% u, you get 12:

In place, if you specify printf to print as% lu, this will cause the memory made in printf to be as follows:

00000000 00001100 00000000 00000000

which corresponds to a long value of 786432

Edit: Passing the value of a variable into the printf function (and not the pointer (and size) of the variable) makes the code anyway. My previous “explanation” basically explained why a warning occurs and why it “usually” is the wrong approach.

+1
Apr 25 '14 at 8:04
source share



All Articles