2016-08-20 2 views
-1

Рассмотрим следующую программу, которая плохо образованный в соответствии со стандартомИнициализировать больше, чем одну не статический член данных объединения

union Test { 
    int s{3}; 
    float f; 
    Test() {}    
    Test(float f) : f(f) {} // this should be error 
    }; 

int main() { 

} 

C++ 11 стандартного N3376 пункта 12 раздела 6.2.8 говорит, что (курсив мой):

попытка инициализации более чем один не статический член данных в союза оказывает программу некорректные.

Но все популярные компиляторы 3 (g ++, clang ++, MSVC++) компилируются выше, не производя компиляторской ошибки или предупреждения. Я думаю, что компилятору необходимо дать диагноз в этой программе. & Программа должна завершиться неудачей при компиляции.

См. Демонстрационную версию live на g ++ here.

См. Демонстрационную версию live на clang ++ here.

Все ли компиляторы разбиты здесь в соответствии со стандартом? Это ошибка компилятора?

+0

Именование параметров 's',' f' или 'data' ничего не меняет. Он используется для инициализации члена 'f'. – Nelfeal

+0

@ Nelxiost, Насколько я понимаю, проблема OP заключается не в присвоении имен переменных, он изменил имена, пытаясь сделать их более ясными для читателей. Проблема заключается в том, как это может компилироваться в этих компиляторах, пока программа считается ** плохо сформированной ** в стандарте. – Mike

+0

@Mike: Посмотрите, что я нашел здесь нечто похожее: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1562 – Destructor

ответ

4

конструктор по умолчанию позволяет s элемент инициализируется, поэтому только один член инициализируется там.

Параметрированный конструктор только инициализирует элемент f, поэтому там также инициализируется только один элемент.

Каждый конструктор позволяет инициализировать только один элемент, поэтому программа хорошо сформирована.


От §12.6.2/9 N4594 (the upcoming C++17 standard):

В не делегировании конструктора, если данный потенциально построен подобъектом не обозначается MEM-инициализатора-ID (в том числе в случае, когда нет мем-инициализатора-лист, так как конструктор не имеет CTOR-инициализатору), затем

  • (9,1) - если юридическое лицо является членом нестатических данных, который имеет член по умолчанию инициализатору (9.2) и либо

    • (9.1.1) - класс конструктора является объединением (9,3) , и ни один другой вариант этого объединения не назначен mem-initializer-id ...

    [Unrelated текст]

Что в основном говорит выше цитата, что скобка или равно-инициализатор будет выполняться, только если нет мем-инициализатор-идентификатор.

В стандарте также есть язык, в котором говорится, что союз может иметь только один скользящий или равный инициализатор.

+2

Почему второй конструктор инициализирует только 'f'? Если 'Test' был структурой, он инициализировал бы обоих членов. – Nelfeal

+2

Это все еще не отвечает на мой вопрос. – Destructor

+2

Вы имеете в виду, что инициализация 'int s {3};' встречается только в конструкторе по умолчанию 'Test()' и игнорируется в конструкторе 'Test (float f)'? – Mike

0

Это не плохо формируется как s является параметр конструктора

+0

Теперь это называется f. Та же логика применяется –

+1

Тем не менее, она не отвечает на мой вопрос. Проблема не в идентификаторах. – Destructor

+1

удалите этот неправильный ответ !!! – Destructor

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