Why does ostream prints `1` for a string defined as `volatile char[]`?

c++, iostream, printf, string, volatile

Solution

The only suitable overload of `operator<<` is that for `bool`, so the array is converted (via a pointer) to `bool`, giving `true` since its address is non-null. This outputs as `1` unless you use the `std::boolalpha` manipulator.

It can't use the overload for `const char *` which would output the string, or that for `const void *` which would output the pointer value, since those conversions would require removing the `volatile` qualifier. Implicit pointer conversions can add qualifiers, but can't remove them.

To output the string, you'd have to cast away the qualifier:

std::cout << const_cast<const char*>(test) << "\n";

but beware that this gives undefined behaviour since the array will be accessed as if it were not volatile.

`printf` is an old-school variadic function, giving no type safety. The `%s` specifier makes it interpret the argument as `const char *`, whatever it actually is.

Problem

Consider this (artificial) example: ``` #include <cstdio> #include <iostream> int main() { volatile char test[] = "abc"; std::printf("%s\n", test); std::cout << test << "\n"; } ``` Compiling it with GCC and running gives the following output: ``` $ g++ test.cc $ ./a.out abc 1 ``` As you can see `printf` prints the string correctly while `cout` prints `1`. Why does writing to `cout` produces `1` in this case?

Original source

Related problems