简体   繁体   中英

A strange phenomenon to initialize struct with GNU C++'s Compound Literals (maybe UB?)

#include <cstdio> // GCC C++17
struct node{int x;}a[5];
signed main()
{
    int i=1;
    a[++i]=(node){i};
    for(int i=0;i<5;++i)printf("%d ",a[i].x);
}

Since C++17, a[++i]=i is not a UB.

According to Sequenced-before rules,

a[++i]=i is equivalent to a[i+1]=i, i+=1 . (in C++17)

But why does the above code run output 0 0 2 0 0 instead of 0 0 1 0 0 ?

When I try:

#include <cstdio> // GCC C++17
struct node{int x;node(){x=0;}node(int _x){x=_x;}}a[5];
signed main()
{
    int i=1;
    a[++i]=node(i);
    for(int i=0;i<5;++i)printf("%d ",a[i].x);
}

there is no such problem, output 0 0 1 0 0 .

I read the GNU documentation but I can't find valid information.

So what is going on?

When i use prefix operator++ „0 0 2 0 0” is exacly what i expect.

I'd say it's a compiler bug. I tried your code with clang 13.0.0 and it produced the output you wanted. Same with icx 3.0.

But as have been pointed out in comments, compound literals are not a part of C++17 standard, so you cannot really expect this to work at all by just looking at the standard.

I don't think that it's a bug. When writing A = B where A is an object, you are calling the function operator=() generated by the compiler and the first parameter of this function is this . So you should look for the evaluation order of function parameters (which is undefined).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM