C言語初心者です。
が下記のものでも実行できる理由を教えてください。
プログラムの省略(?)
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: プログラムの省略(?)
使うコンパイラや年代(バージョン)やコンパイルオプションによって変わるかも知れません。
C言語の規格としては、C99対応コンパイラであればreturn 0;は省略可能です。
intはどうでしたっけ? C言語はダメだった気がするんですが。
C言語の規格としては、C99対応コンパイラであればreturn 0;は省略可能です。
intはどうでしたっけ? C言語はダメだった気がするんですが。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- Dixq (管理人)
- 管理人
- 記事: 1662
- 登録日時: 15年前
- 住所: 北海道札幌市
- 連絡を取る:
Re: プログラムの省略(?)
main の定義は
int main(void)
または
int main(int argc, char *argv[])
でなければならないので、intを省略すると不定になるのではないでしょうか。
「実行できる」のと「正しい」のは異なるので、実行できても安心できません。
レガシーなコードとの互換性を保つために今でも仕方なしに色んな相応しくない決まりが残っている場面はよくあります。
int main(void)
または
int main(int argc, char *argv[])
でなければならないので、intを省略すると不定になるのではないでしょうか。
「実行できる」のと「正しい」のは異なるので、実行できても安心できません。
レガシーなコードとの互換性を保つために今でも仕方なしに色んな相応しくない決まりが残っている場面はよくあります。
Re: プログラムの省略(?)
C89 (ANSI-C)ですと、型を省略するとint型ということになりますから、mainの戻り値は(C89の規格的には)省略可能です。
C99の規格は今ざっと目を通したのですが、型省略時にintになるという記述は見つかりませんでした。
をclangとgccを用い、c89, c99モード両方でコンパイルしたところ、下記のようなメッセージを得ました。
clangやgccが完全に規格に沿ってるとはいえないと思いますが、何らかの参考にはなるでしょうか。
この結果から、どうやらC89ではmainのreturnは省略できないが、型名の省略はできる。
C99ではmainのreturnは省略できるが、関数定義の引数の型名の省略はできない。
と言えるかもしれませんね。
C99の規格は今ざっと目を通したのですが、型省略時にintになるという記述は見つかりませんでした。
をclangとgccを用い、c89, c99モード両方でコンパイルしたところ、下記のようなメッセージを得ました。
uchan@uchan-mbp:ctest1$ clang -Wall -std=c89 -pedantic main.c
main.c:1:6: warning: parameter 'b' was not declared, defaulting to type 'int' [-pedantic]
f(a, b)
^
main.c:1:3: warning: parameter 'a' was not declared, defaulting to type 'int' [-pedantic]
f(a, b)
^
2 warnings generated.
uchan@uchan-mbp:ctest1$ clang -Wall -std=c99 -pedantic main.c
main.c:1:6: warning: parameter 'b' was not declared, defaulting to type 'int' [-pedantic]
f(a, b)
^
main.c:1:3: warning: parameter 'a' was not declared, defaulting to type 'int' [-pedantic]
f(a, b)
^
main.c:1:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
f(a, b)
^
main.c:6:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
main(void)
^~~~
4 warnings generated.
uchan@uchan-mbp:ctest1$ gcc -Wall -std=c89 -pedantic main.c
main.c:2: warning: return type defaults to ‘int’
main.c:7: warning: return type defaults to ‘int’
main.c: In function ‘main’:
main.c:8: warning: control reaches end of non-void function
uchan@uchan-mbp:ctest1$ gcc -Wall -std=c99 -pedantic main.c
main.c:2: warning: return type defaults to ‘int’
main.c: In function ‘f’:
main.c:2: warning: type of ‘a’ defaults to ‘int’
main.c:2: warning: type of ‘b’ defaults to ‘int’
main.c: At top level:
main.c:7: warning: return type defaults to ‘int’
この結果から、どうやらC89ではmainのreturnは省略できないが、型名の省略はできる。
C99ではmainのreturnは省略できるが、関数定義の引数の型名の省略はできない。
と言えるかもしれませんね。
Re: プログラムの省略(?)
ということで
「下記のものでも実行できる理由を教えてください。」
の答えは
mainのreturn省略について
「C99からのC言語の規格ではmainのreturnを省略するとreturn 0;が補われる(ので正常に動く)。C89では戻り値がintのときに引数なしreturn;に出会うと未定義の値が返されることになっているので、正常に実行できているのは単なる偶然かもしれない。」
mainの戻り値型の省略について
「(少なくともC89までの)C言語の規格ではデフォルトでintとして解釈される(ので正常に動く)。」
「下記のものでも実行できる理由を教えてください。」
の答えは
mainのreturn省略について
「C99からのC言語の規格ではmainのreturnを省略するとreturn 0;が補われる(ので正常に動く)。C89では戻り値がintのときに引数なしreturn;に出会うと未定義の値が返されることになっているので、正常に実行できているのは単なる偶然かもしれない。」
mainの戻り値型の省略について
「(少なくともC89までの)C言語の規格ではデフォルトでintとして解釈される(ので正常に動く)。」
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: プログラムの省略(?)
基本的に省略できてもしないほうが安全です。Jimmy さんが書きました:みなさんありがとうございます。コンパイラにも様々な規格があるんですね。慣れてきたら省略できるところを省略していきたいと思います。
環境を自ら限定する書き方を学ぶよりも、どんな環境でも問題ない書き方を学ぶほうが有意義ですね。
※ 初心者は省略がかっこいいと思う傾向が有るようですが大抵の場合は害になります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
-
qwerty
Re: プログラムの省略(?)
解決済みの質問ですが、少し疑問に思ったことを書き込ませてもらいますね。
コンパイラ次第というのは2つの意味があると思うのです。
1、規格がある
2、コンパイラも人が作っている
ここではみなさん質問の「下記のものが実行できる理由」について
主に1の意味で回答されていますが、質問者さんは2を理解されているのか少し疑問に思いました。
現場では規格にあるからとそれを信用してはいけませんよね。
その規格通りに動くようにコンパイラを作るのもまた人間なのですから。
コードの文法については、規格に書いてあるから絶対ではなく、プログラマとしては規格準拠か否かで線引きしないとキリがないということですよね。
ここをよく理解していないと、「慣れてきたら省略できるところを省略していきたい」というような文言が出てくるのかな、と。
そういう意味では、「どんな環境でも問題ない書き方を学ぶ」というのもまた少し誤解を与える表現かと思います。
コンパイラ次第というのは2つの意味があると思うのです。
1、規格がある
2、コンパイラも人が作っている
ここではみなさん質問の「下記のものが実行できる理由」について
主に1の意味で回答されていますが、質問者さんは2を理解されているのか少し疑問に思いました。
現場では規格にあるからとそれを信用してはいけませんよね。
その規格通りに動くようにコンパイラを作るのもまた人間なのですから。
コードの文法については、規格に書いてあるから絶対ではなく、プログラマとしては規格準拠か否かで線引きしないとキリがないということですよね。
ここをよく理解していないと、「慣れてきたら省略できるところを省略していきたい」というような文言が出てくるのかな、と。
そういう意味では、「どんな環境でも問題ない書き方を学ぶ」というのもまた少し誤解を与える表現かと思います。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: プログラムの省略(?)
確かに規格準拠は現場では問題になりますね。qwerty さんが書きました:解決済みの質問ですが、少し疑問に思ったことを書き込ませてもらいますね。
コンパイラ次第というのは2つの意味があると思うのです。
1、規格がある
2、コンパイラも人が作っている
ここではみなさん質問の「下記のものが実行できる理由」について
主に1の意味で回答されていますが、質問者さんは2を理解されているのか少し疑問に思いました。
現場では規格にあるからとそれを信用してはいけませんよね。
その規格通りに動くようにコンパイラを作るのもまた人間なのですから。
コードの文法については、規格に書いてあるから絶対ではなく、プログラマとしては規格準拠か否かで線引きしないとキリがないということですよね。
ここをよく理解していないと、「慣れてきたら省略できるところを省略していきたい」というような文言が出てくるのかな、と。
そういう意味では、「どんな環境でも問題ない書き方を学ぶ」というのもまた少し誤解を与える表現かと思います。
現実問題として、隅から隅まで完全に規格準拠で規格にある機能しか搭載していないコンパイラは皆無だと思います。
まぁ、よく使う環境の範囲内で出来るだけ支障のない書き方で統一するってが現場対応です。
あとコンパイラには規格にない機能を先取りや便利だからと組み込まれている場合も多々あります。あと過去のしがらみで捨てれないとか。
結局のところ、自分のやっていることは規格違反なのか? 必要とされる環境で動くものなのか? 一般的にやその会社や組織の中で好まれる書き方なのか? チームや組織のコーディングルールに違反していないか? あたりを加味して決定されるべきものだと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。