I was testing a c++11 compiler on my source code and it caught an error in one of my functions that I would have expected my non c++11 compiler to catch as well. I was returning false from a function that has a return type of std::string… Here’s the code that demonstrates the problem
#include <iostream>
int main ( )
{
std::string str = false;
std::cerr << "'" << str << "'" << std::endl;
return 0;
}
$ g++ test.cpp -W -Wall -Wextra
$ ./a.out
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct NULL not valid
Aborted
I’m very surprised that this code compiles with no problems. I suspect from the exception description is that the compiler is converting a false to 0 and then to NULL and uses that as a char * to try and construct the string..
However, when I switch false to true, here’s what I get:
$ g++ test.cpp -W -Wall -Wextra
test.cpp: In function ‘int main()’:
test.cpp:5: error: conversion from ‘bool’ to non-scalar type ‘std::string’ requested
That’s a more reasonable result, in my opinion.
Can someone please clarify why this seemingly inconsistent behaviour happens? That is, std::string a = false compiles, but throws an exception, and std::string a = true doesn’t compile.
EDIT:
For reference, here’s an error generated with g++ 4.7 with -std=c++11 for the false case:
test.cpp: In function ‘int main()’:
test.cpp:5:23: warning: converting ‘false’ to pointer type for argument 1 of ‘std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ [-Wconversion-null]
It does accept NULL though as CashCow suggests
It’s rather a horrible implicit conversion and lack of type-safety.
std::stringtakes a constructor from a pointerfalse degrades to 0 which becomes a null pointer.
and you cannot pass a null pointer to the constructor of std::string.
Incidentally whilst you use = it is a constructor not an assignment you are performing here.
Your “strict” g++ C++11 compiler however nicely caught the error for you at compile time.
And it won’t work with true because that is never able to represent a NULL pointer. C++11 has nullptr. If you tried:
std::string str = nullptr;your C++11 compiler would probably compile it and then you’d get a runtime error.