Inspired by my observation in a previous question, I decided to do a little test:
#include <iostream>
#include <sstream>
int main()
{
char c = 'A';
std::stringstream ss("B");
// I know this is bad mojo; that's why I'm testing it
ss >> char(c);
std::cout << c << std::endl;
}
My compiler version:
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.3.0
Thread model: posix
Compiling clang in C++03 mode, it compiles and runs okay:
$ clang++ -Wall -pedantic -std=c++03 test.cpp
test.cpp:9:6: warning: expression result unused [-Wunused-value]
ss >> char(c);
~~ ^ ~~~~~~~
1 warning generated.
$ ./a.out
A
It prints out A
, which is fine, given that this code shouldn't even compile. Switching to C++11 mode, it properly errors when compiling (error: invalid operands to binary expression ('std::stringstream' (aka 'basic_stringstream<char>') and 'int')
).
Yes, in C++03 mode it does give a warning, but it's not a warning I'd expect (I expected some kind of "taking temporary by reference" warning/error, or perhaps a warning/error saying no operator>>
accepts a char
parameter).
My question is: why does the code successfully compile in C++03 mode? Is it using some alternative overload of operator>>
that avoids taking the temporary by reference? Is it being overly lax and letting me take the temporary by reference? I'm puzzled at why clang accepts this code at all; GCC 4.9 properly errors out in C++03/11 modes with a much more relevant error (error: no match for 'operator>>' (operand types are 'std::stringstream {aka std::basic_stringstream<char>}' and 'char')
). Clang's behavior in C++03 mode is puzzling me.
I think it invokes the operator bool()
of std::stringstream
, that is, the code is interpreted as
bool(ss) >> char(c);
which of course is a valid statement with no effect. The implicit conversion to bool
returns !fail()
and is what allows code like
while (ss >> foo)
...
The standard allows to convert to another type that converts to bool
instead of plain bool
(for example a void*
) exactly to avoid this type of problem. Apparently your implementation does not make use of that freedom.
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