10

I've been wondering, how long does a string constant live in C++. For example, if I create some const char *str = "something" inside a function, would it be safe to return the value of str?

I wrote a sample program and was really surprised to see that such returned value still stored that string. Here is the code:

#include <iostream>
using namespace std;

const char *func1()
{
    const char *c = "I am a string too";
    return c;
}

void func2(const char *c = "I'm a default string")
{
    cout << c << endl;
}

const int *func3()
{
    const int &b = 10;
    return &b;
}

int main()
{
    const char *c = "I'm a string";
    cout << c << endl;
    cout << func1() << endl;
    func2();
    func2("I'm not a default string");
    cout << *func3() << endl;
    return 0;
}

It gives me the following output:

I'm a string

I am a string too

I'm a default string

I'm not a default string

10

The func3 is there just to find out if the same works with other types.
So the question is: is it safe to return a pointer to a string constant created within that function (as in func1())?
Also, is it safe to use the default string value as in func2()?

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
SiLiKhon
  • 583
  • 4
  • 15

1 Answers1

16

A string literal has static storage duration and lasts the life of the program. From the draft C++ standard section 2.14.5 String literals paragraph 8 which says (emphasis mine going forward):

Ordinary string literals and UTF-8 string literals are also referred to as narrow string literals. A narrow string literal has type “array of n const char”, where n is the size of the string as defined below, and has static storage duration (3.7).

and from section 3.7.1 Static storage duration paragraph 1:

All variables 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 entities shall last for the duration of the program (3.6.2, 3.6.3).

The second case in func3 on the other other hand is not valid. The lifetime of a temporary bound to a reference persists for the life of the reference, which in this case ends when the function returns. This is covered in section 12.2 which says:

The second context is when a reference is bound to a temporary.115 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:

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
  • Or forever, if it is stored in a ROM. I mean, a pointer can point anywhere, even into ROM. – user1095108 Jul 15 '14 at 13:54
  • Thanks a lot! And what about func3 here? Is its returned value expected to be valid after the function returned to main? – SiLiKhon Jul 15 '14 at 13:55
  • 1
    @SiLiKhon It, in general, will not work. You can see it if you change `int` to a class that has a destructor that yells something like "destructing" when it is going out of scope, and you'll see that the object will be destroyed before you call `cout` on it. In your example, the memory that that integer lives in hasn't been overwritten yet, so you are lucky that it prints the value you are expecting. – triple_r Jul 15 '14 at 14:04