• 締切済み

C言語 プロトタイプ宣言のスコープ

現在、C言語の勉強中です。 プロトタイプ宣言は関数内で宣言をすることは可能でしょうか。 その際、宣言が有効なのはその関数内ということになりますか? OS:windows7 VS2010 express で次のプログラムを記述してもコンパイルエラーにはなりませんでした。 もし、プロトタイプ宣言もスコープを持つとしたら、関数plus()の中でminus() を呼び出したところでwarningかエラーをはくと考えましたが、出ませんでした。 どなたか、教えてください。 #include <stdio.h> int main(void){ char* plus(void); //プロトタイプ宣言 char* minus(void); // char *ans; ans = plus(); printf("mainFunc = %s", ans); ans = minus(); printf("mainFunc = %s", ans); } char* plus(){ char *answer; //関数の戻り値はポインタ answer = minus(); //プロトタイプ宣言なしで関数を使用 printf("plusFunc = %s",answer); return "plus success\n"; } char* minus(){ return "minus success\n"; }

みんなの回答

  • wormhole
  • ベストアンサー率28% (1626/5665)
回答No.7

>LinuxやUnixの環境でテストしなくては >ダメということですね。 どういう事でしょう? もしかしてコンパイル時に警告やエラーが起きないことで、自分のコーディングが正しいかの判定をしようとしてますか? もしそうなのでしたらコンパイル時にエラーや警告もなく、実際に実行して意図した動作をしたとしても、コーディングは間違っている場合もありますのでお気を付けください。 よくあるのはNULLと0の混同。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.6

同意>#5. あの会社は正直なところ「『C++ があるんだから, もう C なんかど~でもいいじゃん』って考えてるんじゃないか」と思えるときがある. 未だに C99 にすら対応してないくらいだし. ちなみに今回の話は「関数へのポインタ」とは全くもって無関係です>#4.

tama_sampo
質問者

お礼

LinuxやUnixの環境でテストしなくては ダメということですね。 ありがとうございました。

  • wormhole
  • ベストアンサー率28% (1626/5665)
回答No.5

>Cのスコープって実際にはコンパイラによって違うんですね。 >っていうか。。。結構、いいかげんなものなのでしょうか? 「VC++のCコンパイラモードでのスコープの扱いはおかしい」という話だと思うんですが・・・ 「いいかげんなのはVC++のCコンパイラモード」といった方がわかりやすいですか?

tama_sampo
質問者

お礼

私の言いたかったことを正確に表現して いただいてありがとうございました。 表現力が乏しくてすみません。。。

回答No.4

まったく違う話になります。 私はこれを見たとき、関数ポインタに見えてしまって。 一緒に勉強してもらえたらと思って、回答してみました。 char hoge() { return ('A'); } main () { char *abc(); abc=hoge; abc(); // この場合、abcは関数のプロトタイプではなく、char (*abc)();というポインターそのもの。 } 多分この書式のせいで、コンパイラーによって、問題が出るのかもしれません。。 正式なプロトタイプは char* plus(void);//プロトタイプ宣言 なら、 typedef char * (FUNC)(void); ということで、これらが問題を起こしているのかも、と 私はちょっと、推測してしまいました。

tama_sampo
質問者

お礼

勉強になりました。 ありがとうございました。 関数のポインタ宣言は私のコンパイラでは char *abc() //エラー char (*abc)() //OK でした。こちらも環境依存かも? あわてて、勉強したので返信がおそくなってしまいました。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

あ~, たぶんわかった. C において 1つのプログラムに「同じ外部名を持つ実体」は 1つしか存在できない. だから, 当該プロトタイプの「本来のスコープ」から外れても「その外部名である以上それだ」と判断できるってことじゃないかな. ちなみに gcc だと (こっちは逆にスコープを「正しく」判断した結果として) エラーになりますね. そして main と plus を入れ替えると VC はアホなエラーメッセージを出しやがる. #2 の話は, おそらく単純なバグ.

tama_sampo
質問者

お礼

ありがとうございました。 Cのスコープって実際にはコンパイラによって違うんですね。 っていうか。。。結構、いいかげんなものなのでしょうか?

回答No.2

main関数を少し変えて、 #include <stdio.h> int main(void){ char* plus(void);//プロトタイプ宣言 int minus; { char* minus(void);// char *ans; ans = plus(); printf("mainFunc = %s", ans); ans = minus(); printf("mainFunc = %s", ans); } minus=-1; } これでも、文法違反はないはずですが、Visual StudioのCコンパイラではエラーになります。 同じVisual StudioのC++コンパイラを使うとエラーにはなりません。Cコンパイラのバグかもしれません。

tama_sampo
質問者

お礼

ありがとうございました。 cygwinのgccでいただいたsampleのコードをコンパイルしました。 おっしゃる通りエラーはなく実行できました。 こちらはVSのcコンパイラのバグだと理解しました。 mainの中のブロック内で宣言したプロトタイプのスコープは 予想通りでしたが、なぜmain直下に記述したプロトタイプは main外の関数で有効になるのでしょうか? しつこくて、すみません。 #include <stdio.h> int main(void){ char* plus(void);//プロトタイプ宣言 //char* minus(void); //ここで宣言した場合はmainの外でも有効? int minus; { char* minus(void);//ここで宣言したので、当然、plus()では無効 char *ans; ans = plus(); printf("mainFunc = %s", ans); ans = minus(); printf("mainFunc = %s", ans); } minus=-1; } char *plus(){ char *minus(void);//再度、プロトタイプ宣言 char *ans; ans = minus(); printf("%s", ans); return "plus\n"; } char *minus(){ return "minus\n"; }

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

そもそも C ではプロトタイプなしで関数を呼び出してもエラーにはなりません. でもって, プロトタイプ宣言自体は「普通の」規則に従ったスコープを持ちます.

関連するQ&A