2017/04/11

[c/c++]gccではglobalでstructのinitializerにconst intは代入できない

タイトルを見てもなんだかわからないと思うので、ソースを載せる。

#include <stdio.h>

static const int A = 1;
static const char B[] = "abc";

static const struct {
    int a;
    const char *b;
} VAL[] = {
    { A, B }
};

int main(int argc, char *argv[])
{
    printf("a=%d, b=%s\n", VAL[0].a, VAL[0].b);

    return 0;
}

これをgccでコンパイルすると、エラーになる。

$ gcc -Wall -o tst test.c
test.c:10:7: error: initializer element is not constant
     { A, B }
       ^
test.c:10:7: note: (near initialization for 'VAL[0].a')

 

確かC++だと、const値は定数扱いだったような気がするので、g++にしてみる。

$ g++ -Wall -o tst test.c
$

うん、OKだ。

 

ただ、gccでもこれはOKだ。

#include <stdio.h>

static const int A = 1;
static const char B[] = "abc";

int main(int argc, char *argv[])
{
    const struct {
        int a;
        const char *b;
    } VAL[] = {
        { A, B }
    };

    printf("a=%d, b=%s\n", VAL[0].a, VAL[0].b);

    return 0;
}

staticを外して、関数の中に入れただけだ。
もしstaticを外さなかったら、やはりエラーになる。

やっぱりCだと、constはダメなのか。

 

これは、通るのだ。

#include <stdio.h>

//static const int A = 1;
#define A (1)
static const char B[] = "abc";

static const struct {
    int a;
    const char *b;
} VAL[] = {
    { A, B }
};

int main(int argc, char *argv[])
{
    printf("a=%d, b=%s\n", VAL[0].a, VAL[0].b);

    return 0;
}

整数の方だけをマクロにしたのだ。
なぜポインタの方はエラーにならないのだろうか?

 

#include <stdio.h>

//static const int A = 1;
#define A (1)
static const char B[] = "abc";
static const char *C = B;

static const struct {
    int a;
    const char *b;
} VAL[] = {
    { A, C }
};

int main(int argc, char *argv[])
{
    printf("a=%d, b=%s\n", VAL[0].a, VAL[0].b);

    return 0;
}

Bは、ポインタと言うよりは、そのアドレスからデータが始まっているからよいのか?
だったら、intだって似たようなものだと思うのだ。

納得がいく理由が導き出せないが、g++だと通るところからすると、値を解決するタイミングが違うとか、そういうことだろうか。。。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。