简体   繁体   中英

Where in the Standard does it say that the default member initializer for U::j should be ignored by the compiler?

Consider the following snippet:

#include <iostream>
union U{
    U(): i(1) {}
    int i;
    int j = 2;    // this default member initializer is ignored by the compiler
};

U u;

int main(){
    std::cout << u.i << '\n';
    std::cout << u.j << '\n';
}

The code prints (see live example ):

1
1

Where in the Standard does it say that the default member initializer for the member U::j is ignored by the compiler?

Note that the union below doesn't compile and this is OK according to [class.union.anon]/4 . I was thus expecting the snippet above also not to compile.

See live example :

union U{
    int i = 1;
    int j = 2;
};

Where in the Standard does it say that the default member initializer for the member U::j is ignored by the compiler?

See [class.base.init] paragraph 9 bullet 9.1 in the C++17 CD.

NB your demo has undefined behaviour, because the active member of the union is i but you read from j . This works with some compilers as a non-standard extension, but is not allowed in ISO C++.

Note that you are declaring a union object, where all members share the same memory area - member variables turn into different "typed views" of the same data.

Thus, as members i and j are effectively stored in the same memory location, any initialization you perform on j (with the initializer) will be overwritten by your constructor setting i.

Just for test, remove the initialization of i from the constructor:

#include <iostream>
union U{
    U() {}
    int i;
    int j = 2;    // this initializes both i & j
};

U u;

int main(){
    std::cout << u.i << '\n';
    std::cout << u.j << '\n';   
}

The output would be

2
2

Update: As per @Ayrosa comments and being just intrigued, I modified the original snippet to perform some initialization with a function (instead of a constant) to induce side effects.

#include <iostream>

int static someStatic()
{
    std::cout << "Initializer was not ignored\n";
    return(2);
}

union U{
    U(): i(1) {}
    int i;
    int j = someStatic();    // this default member initializer is ignored by the compiler
};

U u;

int main(){
    std::cout << u.i << '\n';
    std::cout << u.j << '\n';
}

Result was:

1
1

Meaning that the call to someStatic() was, in fact, ignored by the compiler.

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