문제는 이게 전혀 designated initializer처럼 행동하지 않는다는 겁니다.
저도 처음 보는거라 몇가지 테스트해봤는데, 시험 삼아 다음 코드를 돌려보세요.
#include <iostream>struct Test {int a, b;};int main(){
Test t ={ t.b=1, t.a=0};
std::cout<< t.a<< t.b<< std::endl;return0;}
정말 C99의 designated initializer를 확장시킨 표현이라면 출력 결과는 01이 나와야 하지만, 00이 출력됩니다.
저도 이런 구문은 본적이 없어서 표준에서 보장하는 적법한 구문인지 GCC의 확장인지 또는 버그인지 모르겠습니다.
다만 이로부터 유추해보면 결국 (적어도 GCC에서 이 구문에 대해서) {}는 평범한 initializer-list처럼 작동하며, t.b=1은 a를 초기화하는 구문이되고, t.a=0은 b를 초기화하는 구문이 되며, 마지막에 t.a=0으로 a를 덮어씌우면서 그 값으로 b를 초기화하기 때문에 둘다 0이되는 걸로 보입니다.
"union initialization"으로 구글을
"union initialization"으로 구글을 검색해보니 여러 가지가 자료가 나오네요.
Designated initializer 라고 부르는 모양입니다.
- http://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html
- http://stackoverflow.com/questions/7008784/how-to-initialize-a-union-object
C99에서 새로 지원되는 기능이고,
과거 C89에서 아래와 같이 union 정의와 초기화를 따로 하던 것을 한 번에 할 수 있게 되었네요.
designated initializer는
designated initializer는 공용체/구조체/배열의 변수명을 적지 않습니다. 그리고 C++에는 해당되지 않는 내용입니다.
결론: 말씀하신 바가 맞는 것 같고, 코딩할때도 그런
결론: 말씀하신 바가 맞는 것 같고, 코딩할때도 그런 원칙을 따르는 것이 좋을 것입니다.
----
다만 컴파일러에 따라서는 엄밀히 표준대로 행동하기도 하고 좀 느슨하게 행동하기도 합니다.
저는 gcc/g++ 4.1.2와 4.4.7을 가지고 몇 가지 실험해보고 댓글을 달았던 것인데,
gcc/g++에서는 좀 느슨하게 처리되더군요.
우선 gcc로 컴파일할 때는 union 이름(test.)을 빼야 맞겠지만, 지정하더라도 컴파일러가 받아줍니다.
(컴파일시 gcc extension을 끄도록 -ansi (== -std=c89) 또는 -std=c99 옵션을 줘봐도 결과는 마찬가지였습니다)
g++로 컴파일할 때는 C++에 이런 문법이 없으니 그냥 오류가 나야 맞지만
아래와 같이 test.b 식으로 union 이름을 적어주면 컴파일이 되더군요.
( 역시 g++ extention을 끄도록 -ansi (== -std=c++98) 옵션을 줘도 마찬가지임 )
이렇게 특정 컴파일러가 허용하더라도
코딩시에는 C++이 아닌 C에서만 사용하고, 표준대로 union 이름은 넣지 말고 쓰는 것이 좋겠죠.
최초 질문자인 plusb님은 아마도 위의 g++ 컴파일을 해 보고 질문하신 것 같은데,
g++이 허용해준 위 문법을 저는 그냥 designated initializer라고 답변하고
C99에서 정의된 것이라고 얼버무린 것이었습니다.
문제는 이게 전혀 designated
문제는 이게 전혀 designated initializer처럼 행동하지 않는다는 겁니다.
저도 처음 보는거라 몇가지 테스트해봤는데, 시험 삼아 다음 코드를 돌려보세요.
저도 이런 구문은 본적이 없어서 표준에서 보장하는 적법한 구문인지 GCC의 확장인지 또는 버그인지 모르겠습니다.
다만 이로부터 유추해보면 결국 (적어도 GCC에서 이 구문에 대해서) {}는 평범한 initializer-list처럼 작동하며, t.b=1은 a를 초기화하는 구문이되고, t.a=0은 b를 초기화하는 구문이 되며, 마지막에 t.a=0으로 a를 덮어씌우면서 그 값으로 b를 초기화하기 때문에 둘다 0이되는 걸로 보입니다.
union에 대해 생각할 때는 별 문제를 못
union에 대해 생각할 때는 별 문제를 못 느꼈는데,
struct에 해 보니 말씀하신대로 정말 다른 점이 있네요.
C99를 지원하는 gcc를 이용해서 C 컴파일을 해봤습니다.
표준대로 struct 변수명을 주지 않고 초기화하면 각 멤버 지정순서와 무관하게 일관적인 결과가 나오지만
struct 변수명을 주게 되면 기대와는 다른 엉뚱한 결과가 나오네요.
struct 변수명을 주는 (비표준) 초기화방식은 C/C++ 막론하고 어디에서도 쓰지 말고,
표준대로 struct 변수명 없이 쓰고, C 코딩시에만 써야겠군요.
날카로운 지적 감사합니다.
댓글 달기