こんなコードを書くと、Visual C++ 2005 ではエラーになります。

#include <stdio.h>
class A { public: static const float a = 1.0; };
int main(void)
{
    printf("%f\n", A::a);
    return 0;
}
a.cpp(2) : error C2864: 'A::a' : スタティック const 整数データ メンバ以外をクラス内で初期化することはできません

構造体とかならしょうがないとして、float ぐらい初期化させてくれよと思うわけです。

GCC (gcc-c++-4.1.2-54.el5) で -std=c++98 だとどうかなぁと思って試してみると、エラーどころか -Wall -Wextra でも警告にもならず期待通りの動作になります。最適化をかけるとちゃんと数値がインライン展開されます。

じゃあコンパイラが古いせいかな、ということで、Visual C++ 2008/2010/2012 で試したところ、やっぱりエラーになります。えーそんな。

もちろんクラス宣言の外で初期化すればエラーにはならないわけですが、初期化がヘッダファイル内にあると include したコンパイル単位ごとに実体が複数生成されてしまってリンクエラーになり、ソースファイル (*.cpp) 内にあると最適化時に数値をインライン展開することができません。あと2か所に書くことになってダサい。

うーん…

なお、私がやりたいこととしては変数の実体が生成される必要はない(インライン展開されればそれでいい)ため、次善の策として以下のような方法が取れます。

#include <stdio.h>
class A { public: static inline float a() { return 1.0; } };
int main(void)
{
    printf("%f\n", A::a());
    return 0;
}

これだと期待通りの動作になるしちゃんとインライン展開されます。カッコが邪魔ですが。

Trackback

no comment untill now

Add your comment now