Некоторые компиляторы C ++ допускают анонимные объединения и структуры как расширение стандартного C ++. Это немного синтаксического сахара, которое иногда бывает очень полезно.
Какое объяснение препятствует тому, чтобы это стало частью стандарта? Есть технические препятствия? Философский? Или просто недостаточно, чтобы это оправдать?
Вот пример того, о чем я говорю:
struct vector3 {
union {
struct {
float x;
float y;
float z;
};
float v[3];
};
};
Мой компилятор примет это, но предупреждает, что «безымянная структура / объединение» является нестандартным расширением C ++ .
struct { int i; } a; a.i = 0;
(у типа нет имени). Второй - это тот, который C ++ не поддерживает:struct { int i; }; i = 0;
(у типа нет имени, и он ускользает в окружающую область видимости). C ++, однако, делает поддержку как безымянные и анонимные объединения .Ответы:
Как отмечали другие, анонимные объединения разрешены в стандартном С ++, но анонимные структуры - нет.
Причина этого в том, что C поддерживает анонимные объединения, но не анонимные структуры *, поэтому C ++ поддерживает первое для совместимости, но не второе, поскольку оно не требуется для совместимости.
Кроме того, в C ++ нет особого смысла использовать анонимные структуры. Использование вы демонстрируете, чтобы иметь структуру , содержащую три поплавков , которые могут быть переданы либо
.v[i]
, или.x
,.y
и.z
, я считаю , результаты в непредсказуемом поведении в C ++. C ++ не позволяет вам писать, скажем.v[1]
, одному члену союза , а затем читать , скажем , из другого члена.y
. Хотя код, который делает это, не редкость, на самом деле он не очень хорошо определен.Возможности C ++ для пользовательских типов предоставляют альтернативные решения. Например:
struct vector3 { float v[3]; float &operator[] (int i) { return v[i]; } float &x() { return v[0]; } float &y() { return v[1]; } float &z() { return v[2]; } };
* C11 явно добавляет анонимные структуры, поэтому будущая версия C ++ может добавить их.
источник
Я скажу, вы можете очистить свое
vector3
объявление, просто используяunion
union vector3 { struct { float x, y, z; } ; float v[3] ; } ;
Конечно, анонимные структуры были расширением MSVC . Но ISO C11 допускает это сейчас, и gcc позволяет это , как и компилятор Apple llvm.
Почему в C11, а не в C ++ 11? Я не уверен, но практически говоря, большинство компиляторов C ++ (gcc ++, MSVC ++ и Apple C ++) их поддерживают.
источник
Не уверен, что вы имеете в виду. Раздел 9.5 спецификации C ++, пункт 2:
Вы тоже можете делать такие вещи:
void foo() { typedef struct { // unnamed, is that what you mean by anonymous? int a; char b; } MyStructType; // this is more of a "C" style, but valid C++ nonetheless struct { // an anonymous struct, not even typedef'd double x; double y; } point = { 1.0, 3.4 }; }
Не всегда очень полезно ... хотя иногда полезно в неприятных определениях макросов.
источник
Союзы могут быть анонимными; см. Стандарт, 9.5 параграф 2.
Какую цель, по вашему мнению, выполняет анонимная структура или класс? Прежде чем размышлять, почему чего-то нет в Стандарте, я хотел бы иметь некоторое представление, почему это должно быть, и я не вижу использования анонимной структуры.
источник
Основываясь на правке, комментариях и этой статье MSDN: Анонимные структуры , я рискну предположить - она плохо согласуется с концепцией инкапсуляции. Я бы не ожидал, что член класса будет возиться с пространством имен моего класса, кроме простого добавления одного члена. Более того, изменения анонимной структуры могут повлиять на мой класс без разрешения.
источник
Ваш код
union { struct { float x; float y; float z; }; float v[3]; };
как
union Foo { int; float v[3]; };
что, безусловно, недействительно (в C99 и ранее).
Причина, вероятно, в том, чтобы упростить синтаксический анализ (в C), потому что в этом случае вам нужно только проверить, что тело структуры / объединения имеет только «операторы декларатора», такие как
Тем не менее, gcc и "другие компиляторы" поддерживают безымянные поля в качестве расширения.
Изменить: анонимные структуры теперь официально поддерживаются в C11 (§6.7.2.1 / 13).
источник
union { ... }
это отличается отstruct { ... }
. Первое верно, второе - нет.union { ... };
недопустимый комментарий неверен.