user333422
user333422

Reputation: 377

When is static string declared in cpp file of namespace initialized?

I have a header file that containing just a namespace

namespace XYZ
{
    void setName(const char* name);
    const char* getName();
}

Source file:

static std::string Name;

void XYZ::setName(const char* name)
{
    Name.assign(name);      
}

const char* XYZ::getName()
{
    return Name.c_str();
}

Now, I am not sure, when Name is initialized.

What if, getName() is called before setName(), then will I get a crash??

According to my understanding of C++, if any function is called in cpp file, then static variables declared in the file will be initialized first.

The reason fro declaring it in .cpp instead of header is to reduce its visibility.

Upvotes: 3

Views: 107

Answers (2)

6502
6502

Reputation: 114559

Objects defined at namespace level are created in some unspecified order before main is entered. The only guarantee you have is that if object a comes before object b in a specific compilation unit then a will be initialized before b. No guarantees of any kind are provided about initialization of top level objects in different compilation units.

In your case the code is safe from a low-level point of view if someone calls getName before setName provided this happens after main has been entered, even if of course the content of the string will be empty and thus it may be or not safe from a logical point of view.

If however you are accessing getName or even setName during the initialization of another global object then all bets are off because you're not even allowed to assign to a not-yet-constructed object.

The solution if you really need this pre-main complex processing is using local statics, e.g.:

std::string& theString() {
    static std::string s;
    return s;
}

const char *getName() {
    return theString().c_str();
}

void setName(const char *s) {
    theString() = s;
}

This is guaranteed to be safe because local statics are initialized the first time their scope is entered (i.e. when you call theString() the first time) even if this happens before entering main.

In my experience is however better to try to avoid any complex processing before main is entered and in particular to avoid anything that for any reason can fail (i.e. accessing files or the network) because debugging becomes much harder and the same applies for processing that happens after the end of main (i.e. in destructors of static-duration objects).

Programming in these two "gray areas" of runtime startup/shutdown can become very difficult because sometimes even tools like debuggers don't work properly.

Upvotes: 4

S.C. Madsen
S.C. Madsen

Reputation: 5256

I believe "global" constructors are executed before entering "main". If several "global" or "static" object constructors are created (in separate .cpp files) you have no guarantee of their constructor-execution order AFAIK.

Upvotes: 1

Related Questions