Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Global const string& smells bad to me, is it truly safe?

I'm reviewing a collegue's code, and I see he has several constants defined in the global scope as:

const string& SomeConstant = "This is some constant text";

Personally, this smells bad to me because the reference is referring to what I'm assuming is an "anonymous" object constructed from the given char array.

Syntactically, it's legal (at least in VC++ 7), and it seems to run, but really I'd rather have him remove the & so there's no ambiguity as to what it's doing.

So, is this TRULY safe and legal and I'm obsessing? Does the temp object being constructed have a guaranteed lifetime? I had always assumed anonymous objects used in this manner were destructed after use...


So my question could also be generalized to anonymous object lifetime. Does the standard dictate the lifetime of an anonymous object? Would it have the same lifetime as any other object in that same scope? Or is it only given the lifetime of the expression?


Also, when doing it as a local, it's obviously scoped differently:

class A
{
    string _str;

public:
    A(const string& str) :
        _str(str)
    {
        cout << "Constructing A(" << _str << ")" << endl;
    }

    ~A()
    {
        cout << "Destructing A(" << _str << ")" << endl;
    }
};

void TestFun()
{
    A("Outer");
    cout << "Hi" << endl;
}

Shows:

Constructing A(Outer); Destructing A(Outer); Hi

like image 833
James Michael Hare Avatar asked Jun 22 '09 17:06

James Michael Hare


People also ask

What is a const string?

A string constant is an arbitrary sequence of characters that are enclosed in single quotation marks (' '). For example, 'This is a string'. You can embed single quotation marks in strings by typing two adjacent single quotation marks.

What is a global constant?

Global Constants. A global constant is a literal value to which you assign a name. Like a global variable, you can access the value of the global constant from any script or 4GL procedure in the application. You set the value for the global constant when you declare it.

How do you declare a global constant?

A constant which is needed in more than one functions can be declared a global constant by declaring it a constant using the reserve word const, initializing it and placing it outside of the body of all the functions, including the main function.


1 Answers

It's completely legal. It will not be destructed until the program ends.

EDIT: Yes, it's guaranteed:

"All objects which do not have dynamic storage duration, do not have thread storage duration, and are not local have static storage duration. The storage for these objects shall last for the duration of the program (3.6.2, 3.6.3)."

-- 2008 Working Draft, Standard for Programming Language C++, § 3.7.1 p. 63

As Martin noted, this is not the whole answer. The standard draft further notes (§ 12.2, p. 250-1):

"Temporaries of class type are created in various contexts: binding an rvalue to a reference (8.5.3) [...] Even when the creation of the temporary object is avoided (12.8), all the semantic restrictions shall be respected as if the temporary object had been created. [...] Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created. [...] There are two contexts in which temporaries are destroyed at a different point than the end of the full-expression. [...] The second context is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference except as specified below."

I tested in g++ if that makes you feel any better. ;)

like image 98
Matthew Flaschen Avatar answered Oct 24 '22 00:10

Matthew Flaschen