C++11 Функция "В инициализации класса" не работает для профсоюзов

Пример минимального кода:

struct B { 
  union U {
    struct S {} s;
    int i = 100;
  }
  u;  
};

Теперь, если мы объявим B obj; тогда obj.u.i назначается значение мусора вместо 100, Смотрите демо здесь. (Значение мусора отличается в зависимости от флагов оптимизации и т. Д.).

Предполагается, что функция "В инициализации класса" должна работать с объединениями.

  • Если да, то каков правильный синтаксис? Или это ошибка G ++?
  • Если нет то что int i = 100; делает?

2 ответа

Решение

Это похоже на ошибку GCC. Стандарт гласит (9.5p2):

Не более одного нестатического члена данных объединения может иметь инициализатор с фигурной или равной скобкой.

В остальном, правила те же, что и для обычного класса.

РЕДАКТИРОВАТЬ: Кроме того, 12.6.2p8:

В не делегирующем конструкторе, если заданный нестатический элемент данных или базовый класс не обозначен с помощью mem-initializer-id (включая случай, когда нет mem-initializer-list, потому что конструктор не имеет ctor-initializer) и сущность не является виртуальным базовым классом абстрактного класса (10.4), то

  • если объект является нестатическим элементом данных, который имеет инициализатор с фигурной или равной скобкой, объект инициализируется, как указано в 8.5;
  • в противном случае, если объект является вариантом члена (9.5), инициализация не выполняется;
  • в противном случае объект инициализируется по умолчанию (8.5).

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

Я думаю, что это так, потому что профсоюз объединяет более одного элемента. Ниже представлен обход синтаксиса:

struct B { 
  union U {
    int i;
  }
  u {100};  
};

int main () {
  B obj;
  std::cout << "obj.u.i = " << obj.u.i << "\n";
}
Другие вопросы по тегам