ページ 11

変数のスコープなんですけど

Posted: 2007年8月23日(木) 15:43
by まだ
早速ですが
例えば、
for(int j; j<N; j++){
.....;
}

のような文で、loop変数jの定義はいったいforの中にあるとみなすべきか
for文の外にあるとみなすべきでしょうか。
あるいはどっかの設定(コンパイラ環境)に決めるもんでしょうか。
時々変わるような感じで、どういうわけでしょうか。
CとC++とは違う?
C++であっても、バージョーンにもよる?

頭混乱してます。

ご教授お願い致します

Re:変数のスコープなんですけど

Posted: 2007年8月23日(木) 19:22
by Hermit
C++ では、昔は for の外でしたが、
現在は、for の中の様です。
確か、ANSI だったかの変更があってから変わったはずです。
どの時点だったかは忘れましたが、BC++ Ver5.5.1 でも中だけなので、だいぶ昔の事の様です。
#include <stdio.h>

int main()
{
    for (int i = 0; i < 10; i++)
	printf("%d\n",i);
//    printf("%d\n",i);  //ここを有効にするとエラーになるかどうかで分かりますよね。
    return 0;
}
C では、gcc Ver3.4.2 で、
foo.c:5: error: 'for' loop initial declaration used outside C99 mode
となるので、ANSI C99 でもたぶんエラーだと思われます。

Re:変数のスコープなんですけど

Posted: 2007年8月23日(木) 19:50
by tk-xleader
VC++2005ではエラーになりましたが。これは中ということになりそうです。

Re:変数のスコープなんですけど

Posted: 2007年8月23日(木) 20:35
by Justy
 ちなみに MSVCはコンパイラオプションで挙動を選べます。 (/Zc:forScope)
http://www.ailight.jp/blog/sha256/archi ... /6683.aspx

Re:変数のスコープなんですけど

Posted: 2007年8月23日(木) 21:14
by toyo
Cでは変数の宣言ができるのはブロックの先頭だけですよね

Re:変数のスコープなんですけど

Posted: 2007年8月23日(木) 21:34
by Justy
>ブロックの先頭だけ
 古いCなら。
 新しいCは C++と同じように宣言できます。

http://seclan.dll.jp/c99d/c99d07.htm#dt19990927

Re:変数のスコープなんですけど

Posted: 2007年8月23日(木) 22:12
by Hermit
>新しいCは C++と同じように宣言できます。
for(int i = 0;;) の様な宣言は、
gcc Ver3.4.2 では出来ないんですけど、
前に書いたように、
error: 'for' loop initial declaration used outside C99 mode
となるのだけど・・・・
#include <stdio.h>
int main()
{
    int i;
    for (i = 0; i < 10; i++)
	printf("%d\n",i);
    int j;
    for (j = 0; j < 10; j++)
	printf("%d\n",j);
    return 0;
}
の様にならコンパイル出来たんですが。
MinGW の gcc のバグでしょうか?

Re:変数のスコープなんですけど

Posted: 2007年8月23日(木) 22:23
by tk-xleader
ちなみに、VC++2005の既定の状態でやりました。C99ならば制御文のブロック化が導入されたので、そのブロック
の中扱いということで良いんじゃないでしょうか。

Re:変数のスコープなんですけど

Posted: 2007年8月23日(木) 22:34
by Justy
gcc Ver3.4.2 では出来ないんですけど
 -std=c99の指定は付けてますか?
 gccは記憶がたしかなら 3.3あたりから使えたような気がします

Re:変数のスコープなんですけど

Posted: 2007年8月23日(木) 22:40
by Hermit
おお、そのオプションが必要だったのですね。
gcc は、Ver3 あたりからはデフォルトで ANSI C99 なのかと思っていた(^^;

Re:変数のスコープなんですけど

Posted: 2007年8月24日(金) 00:28
by tk-xleader
たぶん…
C89→エラー
C99→中
従C++→たぶん外
現C++→たぶん中
ということになるんじゃないでしょうか?

Re:変数のスコープなんですけど

Posted: 2007年8月24日(金) 00:59
by たかぎ
> C89→エラー
> C99→中
> 従C++→たぶん外
> 現C++→たぶん中

これであっています。
C++では、ARMでは外でしたが、標準C++では中になっています。
古い仕様(ARMとそれ以前)に準拠した処理系(代表的なのはVC6)では外になっています。

お礼

Posted: 2007年8月24日(金) 10:27
by まだまだ
皆様
いい勉強になりました。

中か外か
これから変更されないように祈ります。

どうも有難うございました。

Re:お礼

Posted: 2007年8月24日(金) 10:37
by たかぎ
> 中か外か
> これから変更されないように祈ります。

処理系のバグや、古い仕様の復刻版のようなものでない限り、今後変更される可能性はまずありません。

ところで、「外」になる古い処理系では、
#define for if(0);else for
といったマクロを定義して、強制的に「中」にするのが定番の手法です。

追伸

Posted: 2007年8月24日(金) 10:48
by まだまだ
>#define for if(0);else for
>といったマクロを定義して、強制的に「中」にするのが定番の手法です

すごいテクニックですね。
いつも勉強させていただいています。

でも、コンパイラスイッチで変更できるような仕様も含めて、
個人的には好ましくないような感じ、、、

また宜しくお願いします。

Re:追伸

Posted: 2007年8月24日(金) 11:21
by GPGA
>C++では、ARMでは外でしたが、標準C++では中になっています。
現在仕事でARMを使用しているのですが、armcpp.exeでコンパイルを行ったところ、中と判断されました。
armcpp.exeに -v オプションがないので、正確なバージョンがわからないのですが
armcpp.exeのみで起動すると
ARM C++ Compiler, ADS1.2 [Build 838]
 
と表示されるので、おそらくVer1.2かと。

Re:追伸

Posted: 2007年8月24日(金) 12:03
by たかぎ
> 現在仕事でARMを使用しているのですが、armcpp.exeでコンパイルを行ったところ、中と判断されました。

ARM違いです。
ここでいうARMは、The Annotated C++ Reference Manual(邦訳, 注解 C++リファレンスマニュアル)のことです。
http://www.research.att.com/~bs/arm.html

Re:追伸

Posted: 2007年8月24日(金) 14:53
by GPGA
>ARM違いです。
ARM違いでしたか。