65

How would it matter if my C++ code (as shown below) has a string initialized as an empty string :

std::string myStr = "";
....some code to optionally populate 'myStr'...
if (myStr != "") {
    // do something
}

vs. no/null initialization:

std::string myStr;
....some code to optionally populate 'myStr'...
if (myStr != NULL) {
    // do something
}

Are there any best practices or gotchas around this?

RBT
  • 24,161
  • 21
  • 159
  • 240
Saket
  • 45,521
  • 12
  • 59
  • 79
  • 14
    `NULL` (conceptually) is a pointer, and should only be used as such. A `std::string` isn't a pointer, so it shouldn't be combined. PS. the initializations are the same: the ctor of `std::string` sets it to the empty string. – MSalters Jul 19 '12 at 08:58
  • @MSalters hi I agree to your point but then if the types seems to be incompatible why does the compiler doesn't throw an error. I have VS 2010 and it silently initialize the std::string with NULL. – Krishna Oza Sep 01 '14 at 10:23
  • 1
    @Surfing_SO: There's a string constructor which takes a pointer to an array of characters, terminated by a zero char.. You incorrectly did not pass such a pointer (NULL doesn't point to an array of characters, or anything else). This is Undefined Behavior and anything may happen in that case. – MSalters Sep 01 '14 at 10:29
  • As both mentioned "NULL" is not exactly the way it is being initialized. The reason your if works is probably because compiler is implicitly converting both sides to bool and then performs the comparison, which is not what you really wanted. – CommanderHK Oct 21 '14 at 10:04
  • Possible duplicate of [How to allow a std:string parameter to be NULL?](http://stackoverflow.com/questions/6884300/how-to-allow-a-stdstring-parameter-to-be-null) – krlmlr Apr 04 '16 at 13:38

6 Answers6

84

There's a function empty() ready for you in std::string:

std::string a;
if(a.empty())
{
    //do stuff. You will enter this block if the string is declared like this
}

or

std::string a;
if(!a.empty())
{
    //You will not enter this block now
}
a = "42";
if(!a.empty())
{
    //And now you will enter this block.
}
SingerOfTheFall
  • 29,228
  • 8
  • 68
  • 105
29

There are no gotchas. The default construction of std::string is "". But you cannot compare a string to NULL. The closest you can get is to check whether the string is empty or not, using the std::string::empty method..

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • 1
    There is extra temporary when constructing `std::string` and assigning `""` to it. – vladon Sep 29 '15 at 18:27
  • @vladon I'm not really sure what temporary you're referring to, or how assignment is relevant. I can't see a temporary in `a = "";` when `a` is `std::string`, but the question isn't about that. – juanchopanza Oct 22 '16 at 07:49
  • The default construction of `std::string` is not `""`; it is `{}`. Default-constructing avoids having to check the `char const*`, find it is an empty string, and eventually do nothing. That's better. – underscore_d Jul 12 '22 at 20:18
25

Best:

 std::string subCondition;

This creates an empty string.

This:

std::string myStr = "";

does a copy initialization - creates a temporary string from "", and then uses the copy constructor to create myStr.

Bonus:

std::string myStr("");

does a direct initialization and uses the string(const char*) constructor.

To check if a string is empty, just use empty().

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • would not `std::string myStr = "";` invoke a `string(const char*)` constructor? Why do you think a temporary will be created? – Andrew Jul 19 '12 at 08:13
  • @Andrew weird, right? http://stackoverflow.com/questions/11223285/whats-the-motivation-between-having-copy-and-direct-initialization-behave-diffe – Luchian Grigore Jul 19 '12 at 08:13
  • @Andrew It almost certainly won't be created, since the standard gives the implementations explicit leave not to create it. On the other hand, the code must be legal even if the temporary was constructed; i.e., there must be an accessible copy constructor. – James Kanze Jul 19 '12 at 09:17
  • 2
    @JamesKanze yes, but that's an optimization. You can't rely on it. Theoretically, a temp is created. – Luchian Grigore Jul 19 '12 at 09:17
  • Great hint about the empty string initialisation, which is done nearly all the time when people create a new CString. ;) – Andreas Sep 08 '16 at 08:19
8

I would prefere

if (!myStr.empty())
{
    //do something
}

Also you don't have to write std::string a = "";. You can just write std::string a; - it will be empty by default

Andrew
  • 24,218
  • 13
  • 61
  • 90
7

Empty-ness and "NULL-ness" are two different concepts. As others mentioned the former can be achieved via std::string::empty(), the latter can be achieved with boost::optional<std::string>, e.g.:

boost::optional<string> myStr;
if (myStr) { // myStr != NULL
    // ...
}
Adam Romanek
  • 1,809
  • 1
  • 19
  • 36
2

The default constructor initializes the string to the empty string. This is the more economic way of saying the same thing.

However, the comparison to NULL stinks. That is an older syntax still in common use that means something else; a null pointer. It means that there is no string around.

If you want to check whether a string (that does exist) is empty, use the empty method instead:

if (myStr.empty()) ...
Jirka Hanika
  • 13,301
  • 3
  • 46
  • 75