Are compound literals Standard C++?
Asked Answered
B

2

37

Compound Literals are a C99 construct. Even though I can do this in C++ :

#include <iostream>
using namespace std;

int main() {
    for (auto i : (float[2]) {2.7, 3.1}) cout << i << endl;
}

It seems that for example MSVC supports it as an extension. Yet all compilers I can get my hands on, compile the above mentioned code.

So is this a feature available in C++14 ? Is there a different standard term (It looks to me like just creating a temporary using braced initialization) ?


Side Note : "Compound Literals" (or whatever I should call the above) are a pack expansion context ( just to mention a functionality )

Bodkin answered 23/1, 2015 at 18:33 Comment(3)
Ugh, use a std::array<float, 2> and you know it's safe, why bother?Beau
for (auto i : {2.7, 3.1}) cout << i << endl; works just fine and is standard.Eadwina
@Eadwina Real literals are of type double so it isn't the same.Crossfade
C
38

This is an extension that both gcc and clang support. The gcc document says:

As an extension, GCC supports compound literals in C90 mode and in C++, though the semantics are somewhat different in C++.

if you build with -pedantic you should receive a warning, for example clang says (see it live):

warning: compound literals are a C99-specific feature [-Wc99-extensions]

Note, the semantic differences in C++ are not minor and code that would be well-defined in C99 can have undefined behavior in C++ with this extension:

In C++, a compound literal designates a temporary object, which only lives until the end of its full-expression. As a result, well-defined C code that takes the address of a subobject of a compound literal can be undefined in C++.

Crinum answered 23/1, 2015 at 18:37 Comment(0)
E
33
(float[2]) {2.7, 3.1}

is a C99 compound literal. Some compilers support it in C++ as an extension.

float[2] {2.7, 3.1}

is a syntax error.

Given using arr = float[2];,

arr {2.7, 3.1}

is valid C++ that list-initializes a temporary array of two floats.

{2.7, 3.1}

is called a braced-init-list.

Finally, for your code,

for (auto i : {2.7, 3.1}) cout << i << endl;

works equally well and is perfectly valid C++ - this constructs a std::initializer_list<double> under the hood. If you really want floats, add the f suffix to the numbers.

Eadwina answered 23/1, 2015 at 18:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.