プログラムの省略(?)

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Jimmy

プログラムの省略(?)

#1

投稿記事 by Jimmy » 13年前

C言語初心者です。

コード:

 #include<stdio.h>
int main(void){
	printf("Hello,world\n");
	return 0;
}
が下記のものでも実行できる理由を教えてください。

コード:

 #include<stdio.h>
main(){
	printf("Hello,world\n");
} 

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: プログラムの省略(?)

#2

投稿記事 by softya(ソフト屋) » 13年前

使うコンパイラや年代(バージョン)やコンパイルオプションによって変わるかも知れません。
C言語の規格としては、C99対応コンパイラであればreturn 0;は省略可能です。
intはどうでしたっけ? C言語はダメだった気がするんですが。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
Dixq (管理人)
管理人
記事: 1662
登録日時: 15年前
住所: 北海道札幌市
連絡を取る:

Re: プログラムの省略(?)

#3

投稿記事 by Dixq (管理人) » 13年前

main の定義は
int main(void)
または
int main(int argc, char *argv[])
でなければならないので、intを省略すると不定になるのではないでしょうか。

「実行できる」のと「正しい」のは異なるので、実行できても安心できません。
レガシーなコードとの互換性を保つために今でも仕方なしに色んな相応しくない決まりが残っている場面はよくあります。

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: プログラムの省略(?)

#4

投稿記事 by beatle » 13年前

C89 (ANSI-C)ですと、型を省略するとint型ということになりますから、mainの戻り値は(C89の規格的には)省略可能です。
C99の規格は今ざっと目を通したのですが、型省略時にintになるという記述は見つかりませんでした。

コード:

f(a, b)
{
    return a + b;
}

main(void)
{
}
を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’
clangやgccが完全に規格に沿ってるとはいえないと思いますが、何らかの参考にはなるでしょうか。
この結果から、どうやらC89ではmainのreturnは省略できないが、型名の省略はできる。
C99ではmainのreturnは省略できるが、関数定義の引数の型名の省略はできない。
と言えるかもしれませんね。

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: プログラムの省略(?)

#5

投稿記事 by beatle » 13年前

ということで
「下記のものでも実行できる理由を教えてください。」
の答えは

mainのreturn省略について
「C99からのC言語の規格ではmainのreturnを省略するとreturn 0;が補われる(ので正常に動く)。C89では戻り値がintのときに引数なしreturn;に出会うと未定義の値が返されることになっているので、正常に実行できているのは単なる偶然かもしれない。」

mainの戻り値型の省略について
「(少なくともC89までの)C言語の規格ではデフォルトでintとして解釈される(ので正常に動く)。」

Jimmy

Re: プログラムの省略(?)

#6

投稿記事 by Jimmy » 13年前

みなさんありがとうございます。コンパイラにも様々な規格があるんですね。慣れてきたら省略できるところを省略していきたいと思います。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: プログラムの省略(?)

#7

投稿記事 by softya(ソフト屋) » 13年前

Jimmy さんが書きました:みなさんありがとうございます。コンパイラにも様々な規格があるんですね。慣れてきたら省略できるところを省略していきたいと思います。
基本的に省略できてもしないほうが安全です。
環境を自ら限定する書き方を学ぶよりも、どんな環境でも問題ない書き方を学ぶほうが有意義ですね。
※ 初心者は省略がかっこいいと思う傾向が有るようですが大抵の場合は害になります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

qwerty

Re: プログラムの省略(?)

#8

投稿記事 by qwerty » 13年前

解決済みの質問ですが、少し疑問に思ったことを書き込ませてもらいますね。

コンパイラ次第というのは2つの意味があると思うのです。
1、規格がある
2、コンパイラも人が作っている

ここではみなさん質問の「下記のものが実行できる理由」について
主に1の意味で回答されていますが、質問者さんは2を理解されているのか少し疑問に思いました。

現場では規格にあるからとそれを信用してはいけませんよね。
その規格通りに動くようにコンパイラを作るのもまた人間なのですから。

コードの文法については、規格に書いてあるから絶対ではなく、プログラマとしては規格準拠か否かで線引きしないとキリがないということですよね。

ここをよく理解していないと、「慣れてきたら省略できるところを省略していきたい」というような文言が出てくるのかな、と。
そういう意味では、「どんな環境でも問題ない書き方を学ぶ」というのもまた少し誤解を与える表現かと思います。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: プログラムの省略(?)

#9

投稿記事 by softya(ソフト屋) » 13年前

qwerty さんが書きました:解決済みの質問ですが、少し疑問に思ったことを書き込ませてもらいますね。

コンパイラ次第というのは2つの意味があると思うのです。
1、規格がある
2、コンパイラも人が作っている

ここではみなさん質問の「下記のものが実行できる理由」について
主に1の意味で回答されていますが、質問者さんは2を理解されているのか少し疑問に思いました。

現場では規格にあるからとそれを信用してはいけませんよね。
その規格通りに動くようにコンパイラを作るのもまた人間なのですから。

コードの文法については、規格に書いてあるから絶対ではなく、プログラマとしては規格準拠か否かで線引きしないとキリがないということですよね。

ここをよく理解していないと、「慣れてきたら省略できるところを省略していきたい」というような文言が出てくるのかな、と。
そういう意味では、「どんな環境でも問題ない書き方を学ぶ」というのもまた少し誤解を与える表現かと思います。
確かに規格準拠は現場では問題になりますね。
現実問題として、隅から隅まで完全に規格準拠で規格にある機能しか搭載していないコンパイラは皆無だと思います。
まぁ、よく使う環境の範囲内で出来るだけ支障のない書き方で統一するってが現場対応です。
あとコンパイラには規格にない機能を先取りや便利だからと組み込まれている場合も多々あります。あと過去のしがらみで捨てれないとか。

結局のところ、自分のやっていることは規格違反なのか? 必要とされる環境で動くものなのか? 一般的にやその会社や組織の中で好まれる書き方なのか? チームや組織のコーディングルールに違反していないか? あたりを加味して決定されるべきものだと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

閉鎖

“C言語何でも質問掲示板” へ戻る