44

I was working on a little project and came to a situation where the following happened:

std::string myString; #GetValue() returns a char* myString = myObject.GetValue(); 

My question is if GetValue() returns NULL myString becomes an empty string? Is it undefined? or it will segfault?

2
  • 1
    This question is pretty similar: stackoverflow.com/questions/2407711/… Commented May 27, 2012 at 5:37
  • 2
    Microsoft always had a bug where assigning a 0x0 to std::string was OK. By looking at your code it seems like you are a microsoft guy, so it might work for you. But.. otherwise it would trigger a SIGSEGV. Commented May 27, 2012 at 5:55

5 Answers 5

73

Interesting little question. According to the C++11 standard, sect. 21.4.2.9,

basic_string(const charT* s, const Allocator& a = Allocator()); 

Requires: s shall not be a null pointer.

Since the standard does not ask the library to throw an exception when this particular requirement is not met, it would appear that passing a null pointer provoked undefined behavior.

Sign up to request clarification or add additional context in comments.

Comments

15

It is runtime error.

You should do this:

myString = ValueOrEmpty(myObject.GetValue()); 

where ValueOrEmpty is defined as:

std::string ValueOrEmpty(const char* s) { return s == nullptr ? std::string() : s; } 

Or you could return const char* (it makes better sense):

const char* ValueOrEmpty(const char* s) { return s == nullptr ? "" : s; } 

If you return const char*, then at the call-site, it will convert into std::string.

Comments

11

Update:

Since C++23 adopted P2166, it is now forbidden to construct std::string from nullptr, that is, std::string s = nullptr or std::string s = 0 will no longer be well-formed.

2 Comments

This answer seems to refer to initialization at compile time, but it does not tell what will happen when the nullptr is returned from a function where the compiler cannot deduce the value at compile time (as scetched in the question),
So now our constructors have to look like this trash "MyClass( const char *internal_name ) : name{ internal_name ? internal_name : "" } {} Yet another reason to avoid the everything everywhere all at once "standard" library.
9

My question is if GetValue() returns NULL myString becomes an empty string? Is it undefined? or it will segfault?

It's undefined behavior. The compiler and run time can do whatever it wants and still be compliant.

Comments

1

It would be good to understand the reason why the standard library isn't more protective against nullptr.

Defensive coding would suggest that it would be better to not crash if a null is supplied. It is such a common thing to do. If it takes a pointer, then a pointer should be a valid value or at least handled. Whether the interface treats it the same as "" is a matter for the interface definition.

For this reason I always define an input parameter as a reference if a pointer value is not a valid input. This pushes the onus onto the caller to ensure they check a pointer if that's what they have. If I want a pointer then the responsibility it with the function to ensure it does not crash with a nullptr.

Until someone enlightens me, I see this as a bug in the standard library and have been caught out by it on a few occasions.

2 Comments

Yeah... Sometimes it seems standards like to be deliberately obtuse, but I'd guess it's probably a performance thing.
Could have #ifdef ROBUST_IF or #ifndef CRASHY_MCCRASHFACE.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.