Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A BIG bug of VC++? Why does initializer-list not value-initialize a struct?

The C++11 standard 8.5.4.3 says:

"If the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized."

struct A
{
    int get() { return i; }

private:
    int i;
};

int main()
{
    A a = {};

    int n = a.get();
    cout << n << endl;
    // n is a random number rather than 0

    return 0;
}

Is this a bug of VC++? My VC++ is the latest Nov 2012 CTP.

like image 530
xmllmx Avatar asked Dec 16 '12 18:12

xmllmx


People also ask

How do you initialize a struct in C?

Use Individual Assignment to Initialize a Struct in C Another method to initialize struct members is to declare a variable and then assign each member with its corresponding value separately.

Does struct have initializer?

All structs in Swift come with a default memberwise initializer, which is an initializer that accepts values for all the properties in the struct.

What is the advantage of initializer list in C++?

The most common benefit of doing this is improved performance. If the expression whatever is the same type as member variable x_, the result of the whatever expression is constructed directly inside x_ — the compiler does not make a separate copy of the object.


1 Answers

Value-initialization of a non-aggregate class type is covered by 8.5p8. In your case the (non-union) class has an implicitly-declared defaulted default no-parameter constructor (12.1p5), which is not deleted and is trivial (ibid). Thus the second bullet of 8.5p8 applies:

— if T is a (possibly cv-qualified) non-union class type without a user-provided or deleted default constructor, then the object is zero-initialized and, if T has a non-trivial default constructor, default-initialized;

So A should be zero-initialized, and the program should print 0.

On the following program:

struct A { int get() { return i; } private: int i; };
#include <iostream>
int main() {
    char c[sizeof(A)];
    new (c) int{42};
    std::cout << (new (c) A{})->get() << '\n';
}

gcc-4.7.2 correctly outputs 0; gcc-4.6.3 incorrectly outputs 42; clang-3.0 goes absolutely crazy and outputs garbage (e.g. 574874232).

like image 190
ecatmur Avatar answered Oct 19 '22 23:10

ecatmur