ページ 1 / 1
最初の関数について
Posted: 2010年1月02日(土) 02:23
by ICE
ちょっと気になり、調べても解らなかったので質問いたします。
C言語で
int main(void)
void main(void)
int main()
void main()
と最初の関数には色々な書き方があるのですが、差がわかりません。
どういった差があるのでしょうか?
returnを書く以外で差があれば教えて頂きたいです。
もしやのどれを使ってもほぼ変わらないというオチですか・・・?
Re:最初の関数について
Posted: 2010年1月02日(土) 03:08
by sizuma
作ったプログラムを呼び出す側の動作が違うだけで、普通にプログラミングする分には変化ないですね。
普通の処理系だと
int main(void)
ですね。
voidにすると警告を出す処理系もあるようです。
だから、戻り値がvoidの処理系もあるようだ、ってことだけ頭に入れてて自分でプログラミングときは
int main(void)で書くって覚えておけばよいと思います。(コマンドライン引数を受け取るのもあるでしょうけど)
()と(void)の違いですが、Cだと引数のチェックを行わないって意味でしょう。
例えば関数を作ります
int myprint(){
printf("%s","this is my print");
}
これをmainから
myprint();
myprint(12);
myprint("hoge");
と呼び出しても警告もだしません。(VisualC++2008express)
チェックしてないわけですからね。
Cだと、main関数を再帰的に呼び出したり、アドレスを取得できるようなので、そういう時以外は変わりはないと思います。
Re:最初の関数について
Posted: 2010年1月02日(土) 10:31
by Naohiro19
ニコニコ大百科には以下のような記述があります。
http://dic.nicovideo.jp/a/c%E8%A8%80%E8%AA%9E
C言語でのmain関数は
int main(void) { /* ... */ }
int main(int argc, char *argv[/url]) { /* ... */ }
と定義するか、
int main(int argc char** argv) { /* ... */ }
のような同等の定義か、処理系依存の定義をしなければならない。(C99 5.1.2.2.1)
よって、
void main(void) { /* ... */ }
は、C言語の規格上定義されていない。
また、return せずに main 関数の最後まで到達した場合、main 関数は 0 を返したことになる。
int と互換性の無い型の値を返した場合には不定となる。(C99 5.1.2.2.3)
Re:最初の関数について
Posted: 2010年1月03日(日) 18:08
by ICE
やはり基本的にはあまり変わらないのですね。
ありがとうございました!
Re:最初の関数について
Posted: 2010年1月03日(日) 18:34
by たかぎ
> やはり基本的にはあまり変わらないのですね。
どう解釈すればそういう結論になるのかわかりません。
Cでは、
int main(void)
または
int main(int argc, char *argv[/url])
か、このいずれかと等価な形式しか移植性がありません。
int main()
は、実質的な問題はありませんが、
void main(void)
のような返却値の型がint以外のものは、完全に移植性が損なわれます。
簡単に移植性を保てる方法があるのに、あえてそれに背を向ける選択をするのは、ちょっと理解できませんね。
Re:最初の関数について
Posted: 2010年1月03日(日) 19:06
by たかぎ
自己レスです。
> int main()
> は、実質的な問題はありませんが、
そういえば、これも実質的な問題がないとはいえませんでした。
NC30WAやNC308WA(M16CやM32Cのコンパイラ)では、main()とする場合とmain(void)とする場合で、生成されるアセンブリ言語におけるシンボルが変わったように記憶しています。
確か、前者が .main で、後者が _main だったような...(うろ覚えです)。
結果として、(ホスト環境向けの)規格通りにスタートアップを実装した場合、main() とすればリンクエラーになります。
Re:最初の関数について
Posted: 2010年1月04日(月) 17:19
by dic
逆におうかがいしたいですが、
void main() として、警告もしくはエラーになる環境(コンパイラ)を列挙していただきたい
Re:最初の関数について
Posted: 2010年1月04日(月) 18:01
by softya
>void main() として、警告もしくはエラーになる環境(コンパイラ)を列挙していただきたい
列挙するまでも無いでしょう。
少なくともgccならデフォルトオプションでwarningが出ます。
それでは納得出来ませんか?
Re:最初の関数について
Posted: 2010年1月04日(月) 18:27
by sizuma
visualstudioもデフォルトで(たしかレベル3)警告が出ますね。
Re:最初の関数について
Posted: 2010年1月04日(月) 19:02
by たかぎ
警告やエラーが出ようが出まいが、未定義の動作である以上、void main()のような記述は行うべきではありません。
この件に限らず、未定義の動作になる記述の多くはエラーも警告も出ません。
Re:最初の関数について
Posted: 2010年1月04日(月) 21:59
by dic
#include <stdio.h>
int myprint(){
printf("%s","this is my print");
}
typedef int (*PFUNC)();
int main()
{
myprint();
myprint(12);
myprint("hoge");
PFUNC kansu = myprint;
kansu();
kansu(12);
kansu("hoge");
return 0;
}
をVC++6.0でコンパイルしたらコンパイルエラーがでるんですが・・・
C:\hoge\main.cpp(12) : error C2660: 'myprint' : 関数が不正な 1 個の実引数をともなって呼び出されました。
C:\hoge\main.cpp(13) : error C2660: 'myprint' : 関数が不正な 1 個の実引数をともなって呼び出されました。
C:\hoge\main.cpp(17) : error C2197: 'int (__cdecl *)(void)' : 実引数が多すぎます。
C:\hoge\main.cpp(18) : error C2197: 'int (__cdecl *)(void)' : 実引数が多すぎます。
VC++ Express でもコンパイルしてもコンパイルエラーですけど・・・
コンパイルしています...
main.cpp
c:\コピー ~ hoge\main.cpp(12) : error C2660: 'myprint' : 関数に 1 個の引数を指定できません。
c:\コピー ~ hoge\main.cpp(13) : error C2660: 'myprint' : 関数に 1 個の引数を指定できません。
c:\コピー ~ hoge\main.cpp(17) : error C2197: 'PFUNC' : 呼び出しに対する引数が多すぎます。
c:\コピー ~ hoge\main.cpp(18) : error C2197: 'PFUNC' : 呼び出しに対する引数が多すぎます。
ビルドログは "file://c:\コピー ~ hoge\Debug\BuildLog.htm" に保存されました。
hoge - エラー 4、警告 0
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========
もしかしたら関数へのポインタを使った場合の話ではないかと思い
付け加えてます
Re:最初の関数について
Posted: 2010年1月04日(月) 22:03
by dic
#include <stdio.h>
int main()
{
int s;
printf( "%d\n", s );
return 0;
}
VC++ 6.0 の警告
コンパイル中...
main.cpp
C:\hoge\main.cpp(6) : warning C4700: 値が割り当てられていないローカルな変数 's' に対して参照が行われました。
リンク中...
VC++ Express の警告
コンパイルしています...
main.cpp
c:\コピー ~ hoge\main.cpp(6) : warning C4700: 初期化されていないローカル変数 's' が使用されます
マニフェストをリソースにコンパイルしています...
と最近では警告でます
報告でした
Re:最初の関数について
Posted: 2010年1月04日(月) 22:22
by sizuma
C言語の話ですよね。(一番上の投稿にC言語で、とあるので)
>C:\hoge\main.cpp(12) : error C2660: 'myprint' : 関数が不正な 1 個の実引数をともなって呼び出されました。
C++でコンパイルしてますよ。
Re:最初の関数について
Posted: 2010年1月05日(火) 10:36
by dic
確認しました
たしかにCではコンパイル、実行までできますね