Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

returning reference to local temporary object on pointer dereferencing

Clang compiler produces warning compiling this code snippet and I can't figure out why.

const int* Get() {
    static const int ARRAY[4] = {1, 2, 3, 4};
    return &ARRAY[0];
}

const int& Test() {
    const auto& p = Get();
    return (*p);
}

warning: returning reference to local temporary object [-Wreturn-stack-address] 
    return (*p);

GCC shows no warnings on this code. I can fix the snippet like this: const auto p = Get(); But I want to know if there is some temporary object and the problem lies deeper

like image 904
Dmitriy Avatar asked Nov 16 '15 13:11

Dmitriy


2 Answers

That warning is a false positive, since the pointee of p is not a temporary, despite p referring to one. There are more scenarios in which that warning is produced spuriously; See e.g. Bug 21218, which uses

char * f() {
    typedef char* t;
    const t & r = new char[5];
    return r;
}

Presumably, if the return type is a reference, Clang looks for const-references (that have been bound to temporaries) in the returned expression, without considering how they're used.

like image 78
Columbo Avatar answered Oct 20 '22 23:10

Columbo


Answer: Clang's warning is incorrect.

Let's step through what happens here:

  1. static const int ARRAY[4] = {1, 2, 3, 4}; constructs a global array of ints
  2. return &ARRAY[0]; returns a pointer to the first element of the global array
  3. const auto& p = Get() stores a reference to a pointer to the first element of a global array
  4. return (*p); creates a reference to the lvalue of the first element of the global array

4 is the tricky one. Clang seems to incorrectly think that *p is a local value, when in fact we know that it is a global.

Crucial to this proof is the fact that *p returns an lvalue.

like image 20
Jonathan Mee Avatar answered Oct 20 '22 21:10

Jonathan Mee