2016-08-04 4 views
3

Следующий фрагмент кода prints 0 compiled with vc++ и prints 1 compiled with g++ or clang++:Visual C++ инициализация несогласованности с НКУ и лязгом

#include <iostream> 
#include <vector> 

struct S 
{ 
    S() = default; 

    std::vector<int> v{0};   
}; 

int main() 
{ 
    std::vector<S> s{{}}; 

    std::cout << s.front().v.size() << std::endl; 
} 

Является ли это ошибка в ВХ ++?

Если предоставлен пользовательский конструктор (S() {}; вместо S() = default;) vc++ starts to print 1, too.

+1

Выглядит действительно как ошибка компилятора в компиляторе vC++. –

+1

Я, кажется, помню, что на C++ 17 ожидается предстоящее изменение в отношении фигурного скоринга с одним элементом. Что произойдет, если вы измените значение 0 на 13? –

+0

@ Cheersandhth.-Alf, например. 'std :: vector v {11,22};' создает ту же проблему. –

ответ

3

При чтении Standard (C++ 11 n3485), 12.6.2/9 утверждает, что:

Если данный нестатический член данных имеет как brace-or-equal-initializer и mem-initializer, инициализация задается mem-initializer выполняется , а нестатический элемент данных brace-or-equal-initializer игнорируется.

Поэтому возникает вопрос, если default, то есть неявно определен конструктор содержит mem-initializer или нет.

Раздел 12.1/6 гласит:

неявно определенный конструктор по умолчанию выполняет множество инициализаций класса, которые будут выполняться с помощью написанной пользователем конструктор по умолчанию для этого класса, не ctor-initializer (12.6.2) и пустой compound-statement.

Это будет означать, что неявно создается (по умолчанию) конструктор не имеет mem-initializer с и действительно должны использовать в классе инициализатору (brace-or-equal-initializer в вышеприведенной цитате).

MSVC здесь неправильный (не удивительно, действительно).

1

Это не ответ, а комментарий, требующий кода.

Ниже показаны различия компилятора более четко, я думаю:

#include <iostream> 
#include <vector> 

struct S 
{ 
    S() = default; 

    std::vector<int> v = std::vector<int>(13); 
}; 

int main() 
{ 
    std::vector<S> s{{}}; 
    std::cout << s.front().v.size() << std::endl; 
} 

Здесь г ++ MinGW 5.1.0 сообщает 13 пунктов, в то время как MSVC 2015 обновления 2 отчеты 0 штук.

I.e. g ++ использует инициализатор, указанный в классе, тогда как MSVC использует значение, указанное в объявлении s. Для меня это похоже на проблему с g ++. Но я не уверен: единственная уверенность в том, что оба не могут быть прав.

Смежные вопросы