Why is printf not printing this correctly (but cout is)?

So here's a short overview of what I want to use -> http://preshing.com/20150324/safe-bitfields-in-cpp/

And here is the definition/implementation of the code that I'm using (BitFieldMember at the top and the #defines at the bottom) -> https://github.com/preshing/cpp11-on-multicore/blob/master/common/bitfield.h

Here is some short sample code (using VS2015):
1
2
3
4
5
6
7
8
9
BEGIN_BITFIELD_TYPE(Status, uint32_t)           // type name, storage size
    ADD_BITFIELD_MEMBER(a, 0, 10)         // member name, offset, number of bits
    ADD_BITFIELD_MEMBER(b, 10, 10)
    ADD_BITFIELD_MEMBER(c, 20, 10)
END_BITFIELD_TYPE()

Status test = 0x12345678;
printf("test = %u, test.a = %u, test.b = %u, test.c = %u\n", test, test.a, test.b, test.c);
std::cout << "test = " << test << ", test.a = " << test.a << ", test.b = " << test.b << ", test.c = " << test.c << "\n";


here is the output:
1
2
test = 305419896, test.a = 305419896, test.b = 305419896, test.c = 305419896
test = 305419896, test.a = 632, test.b = 277, test.c = 291


I mean obviously the result is different for printf because the overloaded operator of BitFieldMember doesn't get called but my question is why is that the case (and how can it be fixed)?
Last edited on
When the you pass arguments to a variadic function the compiler doesn't know what types to expect. With printf the types are decided by the format specifier in the first argument but that is just how printf is implemented, nothing the compiler cares about, so the compiler will not automatically call the conversion operator when you pass them to printf. To print the bitfield values correctly you would have to explicitly cast each of the values.

1
2
3
printf("test = %u, test.a = %u, test.b = %u, test.c = %u\n", 
       test.value, static_cast<uint32_t>(ctest.a), 
       static_cast<uint32_t>(test.b), static_cast<uint32_t>(test.c));
Last edited on
Thanks, that indeed works.

But then what is passed to the printf function without the explicit casts? A copy of the struct, a (const) reference or something else?

And wouldn't whatever is passed to printf be cast to an unsigned integer anyway somewhere within the function due to the %u format specifiers?
But then what is passed to the printf function without the explicit casts? A copy of the struct, a (const) reference or something else?

A copy of the struct.


And wouldn't whatever is passed to printf be cast to an unsigned integer anyway somewhere within the function due to the %u format specifiers?

No casting is done in printf (indeed, that would be impossible since printf receives no type information.) The memory is simply interpreted the way the format specifiers specify.

This might be of interest:
https://msdn.microsoft.com/en-us/magazine/dn913181.aspx
Last edited on
Topic archived. No new replies allowed.