クラスのstaticメンバとinline

[戻る]
ToDo 2004/12/06(月) 12:09:59
クラスのstaticなメンバ変数にinlineなメンバ関数からアクセスすると
正常にアクセスできない場合があると聞きました。

// A.h
class A {
public:
  void inline_func();
  void non_inline_func();

  static std::string str;
};
inline void A::inline_func() { std::cout << str; }

// A.cpp
std::string A::str = "hoge";
void A::non_inline_func() { std::cout << str; }

// main.cpp
int main() {
  A a;
  a.inline_func(); // 正常にアクセスできない?
  return 0;
}

ためしにVC++6,0でテストしてみましたが問題ありませんでした。
これはたまたま上手くいっただけで問題があるのでしょうか?

YuO [E-Mail] 2004/12/06(月) 13:53:03
> クラスのstaticなメンバ変数にinlineなメンバ関数からアクセスすると
> 正常にアクセスできない場合があると聞きました。

どこで聞いたのでしょうか。
staticなメンバ関数にinline関数からアクセスすることは正しいですし,
正常にアクセスできないとしたら,それはコンパイラ固有の問題になります。

ToDo 2004/12/06(月) 14:07:40
どこで聞いたのか忘れました・・・
言語的に問題ないということなら安心です。

ToDo 2004/12/06(月) 14:09:13
履歴探ったら見つかりました。
ttp://pc5.2ch.net/test/read.cgi/tech/1101100031/397-
staticメンバの初期化のタイミングの問題らしいのですが・・・

tetrapod 2004/12/07(火) 11:36:44
えーっと、元ネタは2chでの質疑応答で、結局のところ
「静的オブジェクトがいつ初期化されるか」ということになります。

static メンバオブジェクトは非局所オブジェクトと同様に初期化される (9.4.2)
非局所オブジェクトの初期化タイミングの規定 (3.6.2) 

で 2ch では規格書の正確な訳が示されていませんが私なりに正確に表現するなら、
>>3.6.2-3 <snip> 初期化が main の最初の文の実行の時点よりも遅延されるとしたら、
>>その初期化は、そのオブジェクトが初期化されている翻訳単位中で定義されている、
>>どれかの関数またはオブジェクトが最初に使用される時点より先に行われなければならない。

提示の例では
・A::str が「具体的にいつ初期化されるか」は処理系定義。
・ただし a.cpp の中のどれかの関数またはオブジェクトが使用されるより先でなければならな
い。
・この場合まさに A::str が使用されているので、その使用に先立ち必ず初期化される。
ということで、規格書的にも問題ないです。
# 世の中のコンパイラ全てが規格書どおりかというとそんなことは無いが...

main() 実行前の非局所オブジェクトの初期化中に、複数個オブジェクト間の初期化タイミング
に
依存してしまうコードを書いてしまうと問題ありですが。

古いスレッドには追加発言できません。