user3528438
user3528438

Reputation: 2817

Does const qualifier increases the life time of temporary compound literal?

GNU C++ extension implements compound literal differently form C99 in the sense that GNU C++ compound literal is a temporary object and has single-line life time.

So this code gives compile error trying to get the address of such a temporary object:

#include <iostream>
using namespace std;
#include <valarray>

int main() {
    int n = 5;
    std::valarray<int> arr((int[]){1,1,2,2,3}, n);
                          //^^^^^ error here, although the compound literal 
                          // outlives the constructor
    for (int i = 0; i < n; ++i)
        cout << arr[i] << ' ';
    cout << endl;
}

However, by changing (int[]){1,1,2,2,3} to (const int[]){1,1,2,2,3}, this error disappears and the code runs OK.

Then it seems that by adding const qualifier the compound literal's is no longer a temporary.

I know that const reference can increase the life time of temporary object to the life time of the reference, but I don't see how that is related to this question.

So my question is, is above code well defined behavior by C++ standard and/or GNU C++ extension?

Upvotes: 0

Views: 62

Answers (1)

rici
rici

Reputation: 241701

Since it is a GCC extension, it certainly cannot be defined by the C++ standard. As far as the standard goes, the program is not well-formed.

The GNU documentation (as per your link) points out that the const modifier might change the behaviour:

As an optimization, the C++ compiler sometimes gives array compound literals longer lifetimes: when the array either appears outside a function or has const-qualified type. If ‘foo’ and its initializer had elements of ‘char *const’ type rather than ‘char *’, or if ‘foo’ were a global variable, the array would have static storage duration.

But goes on to suggest:

But it is probably safest just to avoid the use of array compound literals in code compiled as C++.

As an aside, since C++11, there is a std::valarray constructor taking an initializer_list, so the following is well-formed in C++11 without GCC extensions:

std::valarray<int> arr{1,1,2,2,3};

Upvotes: 4

Related Questions