Reputation: 2817
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
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