frogstair
frogstair

Reputation: 461

Incorrect passing of uint64_t to va_list

I am writing a custom printf function and a uint64_t seems to be passed incorrectly to va_list:

Problematic point:

printf("Number is %C, and the next one is %C", 0xff00ffb7, 0xffffffff);

Part of my printf implementation that produces the incorrect result:

format++;
uint64_t num = va_arg(parameters, uint64_t);

When debugging with gdb the value of num becomes 0xffffffffff00ffb7 rather than 0xff00ffb7 which I expect, and for the next %C num becomes 0. Is this some standard behavior I'm missing or am I doing something wrong?

Upvotes: 3

Views: 401

Answers (1)

chux
chux

Reputation: 153338

If 0xff00ffb7 is meant to be a uint64_t for a variadic function, cast it.

printf("Number is %C", (uint64_t) 0xff00ffb7);

0xff00ffb7, as an integer constant, has the type of int, unsigned, long, unsigned long, long long or , unsigned long long: the first one it "fits". With 32-bit int/unsigned, 0xff00ffb7 would be unsigned and likely the source of OP's trouble.

Appending u to a constant is a good idea to insure it is some unsigned type.

Appending L or LL to a constant is not a good idea to insure a constant is uint64_t. Either might match (LL often will), but these suffixes do not guarantee that type.

Using UINT64_C(0xff00ffb7) forms a constant of type uint_least64_t which is certainly same as uint64_t on machines that have uint64_t.

Upvotes: 4

Related Questions