Reputation: 63935
So today I wrote a fairly hard to find bug where I initialized a std::string to nullptr (not a pointer to std::string, but the value itself). I've found apparently it's only possible to do in C++11 or later with clang.
#include <string>
#include <iostream>
using namespace std;
class Meh{
int x;
};
class Foo
{
private:
std::string x=nullptr;
Meh y=nullptr; //remove this line and it compiles
public:
std::string z=nullptr;
};
int main(void)
{
Foo f;
cout << f.z;
return 0;
}
As you can see, I tried assigning nullptr to just a random instance of a class and it didn't work. What magic is in string that allows this to work, and in what way is this even valid syntax? I assumed I would be met with a type casting error in this case.
For reference I compiled with this:
clang++ test.cpp -O3 -g -fno-inline -std=c++11 -Wall
It gave no form of warnings, though it would error out if not using C++11
Upvotes: 8
Views: 3529
Reputation: 40199
Why can you assign
nullptr
tostd::string
?
You no longer can, and it only used to be possible because of a historical design flaw.
As of C++23, std::string x = nullptr;
is ill-formed. The reason why it worked originally is because of a constructor which accepts const CharT*
, which could also be a nullptr
:
basic_string( const CharT* s, const Allocator& alloc = Allocator() );
However, this constructor loses in overload resolution against the new constructor:
basic_string( std::nullptr_t ) = delete;
If you tried to compile your code in C++23, you would get a compiler error. In C++11, it would be undefined behavior to run your code.
Since it's pointless to allow = nullptr
as it's always a bug, P2166: A Proposal to Prohibit std::basic_string and std::basic_string_view construction from nullptr proposed to disallow it.
Upvotes: 0
Reputation: 56921
That's simply because there are constructors (number (5) in the link) and assignment operators (number (3) in the link) for std::string
that accept a const char*
, and hence the nullptr
matches.
Before C++11 (and therefore before nullptr
), the same problem occurred when you tried to construct from 0
or NULL
. All those cases were illegal and result in undefined behaviour, although at least one STL (RogueWave?) accepted it in the past and generated an empty string.
Upvotes: 15