こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

-広告-

締切り済みの質問

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";
}

投稿日時 - 2014-04-14 16:00:50

QNo.8554264

すぐに回答ほしいです

このQ&Aは役に立ちましたか?

2人が「このQ&Aが役に立った」と投票しています

-広告-
-広告-

回答(7)

ANo.7

>LinuxやUnixの環境でテストしなくては
>ダメということですね。

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

よくあるのはNULLと0の混同。

投稿日時 - 2014-04-16 01:45:25

-広告-

ANo.6

同意>#5. あの会社は正直なところ「『C++ があるんだから, もう C なんかど~でもいいじゃん』って考えてるんじゃないか」と思えるときがある. 未だに C99 にすら対応してないくらいだし.

ちなみに今回の話は「関数へのポインタ」とは全くもって無関係です>#4.

投稿日時 - 2014-04-15 02:00:19

お礼

LinuxやUnixの環境でテストしなくては
ダメということですね。

ありがとうございました。

投稿日時 - 2014-04-15 03:16:59

ANo.5

>Cのスコープって実際にはコンパイラによって違うんですね。
>っていうか。。。結構、いいかげんなものなのでしょうか?

「VC++のCコンパイラモードでのスコープの扱いはおかしい」という話だと思うんですが・・・
「いいかげんなのはVC++のCコンパイラモード」といった方がわかりやすいですか?

投稿日時 - 2014-04-15 01:42:00

お礼

私の言いたかったことを正確に表現して
いただいてありがとうございました。

表現力が乏しくてすみません。。。

投稿日時 - 2014-04-15 03:12:37

まったく違う話になります。

私はこれを見たとき、関数ポインタに見えてしまって。
一緒に勉強してもらえたらと思って、回答してみました。

char hoge() {
return ('A');
}
main () {
char *abc();

abc=hoge;

abc();

// この場合、abcは関数のプロトタイプではなく、char (*abc)();というポインターそのもの。

}

多分この書式のせいで、コンパイラーによって、問題が出るのかもしれません。。

正式なプロトタイプは
char* plus(void);//プロトタイプ宣言
なら、
typedef char * (FUNC)(void);
ということで、これらが問題を起こしているのかも、と
私はちょっと、推測してしまいました。

投稿日時 - 2014-04-15 01:05:15

お礼

勉強になりました。
ありがとうございました。

関数のポインタ宣言は私のコンパイラでは
char *abc() //エラー
char (*abc)() //OK
でした。こちらも環境依存かも?

あわてて、勉強したので返信がおそくなってしまいました。

投稿日時 - 2014-04-15 03:08:27

ANo.3

あ~, たぶんわかった.

C において 1つのプログラムに「同じ外部名を持つ実体」は 1つしか存在できない. だから, 当該プロトタイプの「本来のスコープ」から外れても「その外部名である以上それだ」と判断できるってことじゃないかな. ちなみに gcc だと (こっちは逆にスコープを「正しく」判断した結果として) エラーになりますね.

そして main と plus を入れ替えると VC はアホなエラーメッセージを出しやがる.

#2 の話は, おそらく単純なバグ.

投稿日時 - 2014-04-15 00:37:04

お礼

ありがとうございました。

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

投稿日時 - 2014-04-15 00:58:58

ANo.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コンパイラのバグかもしれません。

投稿日時 - 2014-04-14 19:06:44

お礼

ありがとうございました。
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";
}

投稿日時 - 2014-04-15 00:14:05

ANo.1

そもそも C ではプロトタイプなしで関数を呼び出してもエラーにはなりません.

でもって, プロトタイプ宣言自体は「普通の」規則に従ったスコープを持ちます.

投稿日時 - 2014-04-14 16:48:12

-広告-
-広告-
-広告-
-広告-