C言語の構造体の初期化

gccの勉強を始めました、というわけではないのだけど、VC++ばっかりだったのでgcc拡張構文やCとC++の違いに戸惑うことが多い。今回は(次回があるのか?)構造体の初期化について3種類の構文を。

//test.c
#include <stdio.h>

typedef struct
{
        int id;
        char* name;
} file_struct;


int main(void)
{
        file_struct file_a = { 0, "a", };            // ISO標準
        file_struct file_b = { name:"b", id:1, };    // gcc拡張
        file_struct file_c = { .name="c", .id=2, };  // C99 Designated Initializer


        printf("id=%d, name=%s\n", file_a.id, file_a.name);
        printf("id=%d, name=%s\n", file_b.id, file_b.name);
        printf("id=%d, name=%s\n", file_c.id, file_c.name);
        return 0;
}


当然、うまくいく。

egggarden@egggarden-laptop:~/desktop$ gcc --version
gcc.real (Ubuntu 4.3.3-5ubuntu4) 4.3.3
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

egggarden@egggarden-laptop:~/desktop$ gcc -Wall test.c 
egggarden@egggarden-laptop:~/desktop$ ./a.out 
id=0, name=a
id=1, name=b
id=2, name=c


VC9では、古典的な構文しか受け付けない。

PS C:\Users\egggarden\Desktop> cl /Wall .\test.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

test.c
C:\Program Files\Microsoft Visual Studio 9.0\VC\INCLUDE\stdio.h(381) : warning C4255: '_get_printf_count_output' : no function prototype given: converting '()' to '(void)'
.\test.c(13) : error C2065: 'name' : undeclared identifier
.\test.c(13) : warning C4204: nonstandard extension used : non-constant aggregate initializer
.\test.c(13) : error C2059: syntax error : ':'
.\test.c(14) : error C2059: syntax error : '.'


C++ではそのうちに0xが出てくるので、さらにカオス。「autoよー」「そんな…意味まで変わって…!!」などという悲劇続出。


てかなもうソースレベルで互換性があるなんて思っている人はいないね。
C++0xの十分な実装はgccでもまだまだみたいだし、しばらくは.cppの代わりに.cで遊ぶのが楽しそう。