2008年8月3日日曜日

[プログラミング][C++]これはバグ・・・?[追記あり]

今会社でせっせこツールを作成しております。
で、言語としてはC/C++ってことで、VC++6.0(ちょっと古いっすよねぇ・・・^^;)で開発を行っているのですが、昨日ちと不可解な現象に出くわしました。
私の解釈が間違っていなければ、次のコードは正しいはず。
for(int i=0; i<nSize; i++)
{
snip...
}
snip...
for(int i=0; i<nSize; i++)
{
snip...
}

実際、VC++2005EEではこの手の書き方で問題ありませんでした(メモリとか実行速度効率の是非はともかく)。
が、VC++6.0だと
"iが多重定義されています。"
ってな旨のコンパイルエラーが発生します。上の例では、下のforブロックのiの定義を消してやればコンパイルが通ります。
まぁ実際、ただのループ用一時変数なので関数の頭で宣言したって構いはせんのですが、なんとなく釈然としないんですよねぇ。確かC++では、スコープの概念が導入されてたはずで、forブロックで宣言した変数はforを抜けたら破棄されるはずなんですよね。
別にクリティカルな問題ではないですが、文法的に正しいのならコンパイラのバグってことなのかなぁ? VC++2005EEでは出てないので、コンパイラだけDLしてきて差し替えるって手もあるけど・・・、なんか不具合起きたら嫌だしなぁ。
けどこの手の書き方は結構あると思うので、ひょっとしたら問題が起きてるのかな? どういうキーワードでぐぐったらいいかちょっと分かりにくいけど、まぁなんぞ探してみるとしよう。
WindowsUpdateには更新パッチはなかったからなぁ。ほんと、なんか釈然としないわw
※2008/08/02 18:51 追記
Velnirとひでとさんからのコメントをもらったので、いっちょぐぐってみました。
結果、やはりVC6(VC7も)のコンパイラがC++の標準に準拠していなかったために起きたことのようです。
「/Zc:forScope」
でぐぐったらすぐ出てくると思います。コンパイラにこのオプションを引き渡すと標準C++の挙動通り、上のコードは通るようになります。ちなみにVC8(VC++2005)以降は標準C++に準拠した状態をデフォルトとしているため、上記のコードを書いてもエラーは発生しないとのことのようです>Velnir。 なので、VC++2005EEを使用してきた私はこのエラーに出くわしたことがなかったんですね^^;
つか、VCのコンパイラはあくまでVCのコードをコンパイルするためのもので、標準C++に準拠しているなんて考える方が間違いだったということを今更ながらに実感。そーいやテンプレートの扱いやらがおかしいというか準拠してないって話は出てましたなぁ。
まぁこれはバグというより仕様みたいですけれど、C/C++の勉強にVC++は勧めちゃいけないのかなとか思ってしまった今日この頃でありましたw

5 件のコメント:

  1. SECRET: 0
    PASS: 64fa84376bf93a7a4f06f52e1c5ee8cd
    同じルーチン内だと一回で良かった筈…。
    C++はあんまり詳しくはないが、VC++2005でも同じようなエラーは吐かれた事あったように思う。
    ま、今C言語触ってない人の言葉だから微妙だが。

    返信削除
  2. SECRET: 0
    PASS: e4b80f22d898cb52592353bb9bed743f
    この書き方の解釈はコンパイラによって違ったんじゃなかったかな。

    返信削除
  3. SECRET: 0
    PASS: 74be16979710d4c4e7c6647856088456
    結果はBlog記事に追記しておきましたので、また見てみてください〜>ご両人

    返信削除
  4. SECRET: 0
    PASS: 57e2b1ecc6ea2b620797b1759f54a666
    僕もVC6.0でこの問題に悩まされてました。コンパイラの仕様だったのね。
    なんか中括弧のスコープの概念を悩ましくさせるエラーだったのでずーっと不可解でした。ネタ分かってすっきり。
    ま、ひとつ上のスコープで冒頭にループ用変数の宣言をしてしまうクセがついてますがw

    返信削除
  5. SECRET: 0
    PASS: 64fa84376bf93a7a4f06f52e1c5ee8cd
    私もしーさんに賛成ですな。
    カウンタを何回も使いまわすところなら最初に宣言すれば良いような気がします(セキュアかどうかは別として
    ま、一回しか使わない/使えないカウンタならスコープ内でやるのが普通だけど。
    C使いから見るC++ってこんな程度…。

    返信削除