void main(void)
{
}
などと書いてあるのですが、私が使っている Vine Linux2.5 の gcc だと
main(void)
{
}
としなければ、エラーが出てしまいます。何故なのでしょう?
void さえつけなければ特に不自由なことはないので、
放ってさえおけばいいのですが、
なんとなく気持ち悪いので原因がわかる方がいらしたらお願いします。
ちなみにエラーメッセージはこんな感じです。
$ gcc test.c
test.c: In function `main':
test.c:4: warning: return type of `main' is not `int'
> gccで奇本情報処理のC言語の勉強をしています。
基本情報処理技術者試験のことですか?
下記の記述を見ると「奇本」というのがあながち誤字でもないように
思えてくるのですが…
> 参考書には
>
> void main(void)
> {
>
> }
>
> などと書いてあるのですが、
その参考書の記述が誤りです。main は int で書く、すなわち
/* 例1 */
int main(void)
{
....
}
または
/* 例2 */
int main(int argc, char **argv)
{
....
}
と書く、ということに ISO 規格・JIS 規格で決まっています。
また、関数定義の時の型名 int は省略できる、つまり、単に
/* 例3 */
main(void)
{
....
}
または
/* 例4 */
main(int argc, char **argv)
{
....
}
と書いても例1・例2と同等に扱う、とも規格で決まっています。
なぜそうなっているのかというと、半分は「歴史的理由で昔はそうせざ
るをえなかったから」、半分は「main から返り値を返したい場合もある
から」です。
Microsoft など一部のコンパイラは、「int のほか、void も可とする」
と仕様書に明言していますが、それはあくまでもそのコンパイラメーカー
のローカルルールです。
main からの返り値に何を返せばいいかわからなければ、当座は
return 0; としておけば間違いはありません。調べてみたければ、
たとえば
#include<stdio.h>
int main(void)
{
int a;
printf("Enter an integer:"
scanf("%d",&a);
/* scanf は安易に使わないほうがいいが、ここでは手抜き */
return a;
}
というコードを
$ gcc test.c
のようにコンパイルして、
$ ./a.out
Enter an integer:3
$ echo $?
などと実行してみると面白いでしょう。
以上、ヒントは全部書きました。あとは自分で調べましょう。
☆
というわけで、結論。
その参考書は
規格を理解していない人が書いた、内容的に不正確な本
Windows に特化した内容の本
のどちらかなので、標準の C 言語を勉強したいなら、別の本に買い
換えましょう。将来は Windows 方面で食べていきたい場合でも、
Windows 固有の話だけでなく ISO/JIS の標準もきちんと知っておく
ことはいいことですよ。
========================================================================
飯嶋 浩光 / でるもんた・いいじま http://www.ht.sakura.ne.jp/~delmonta/
IIJIMA Hiromitsu, aka Delmonta [PC] mailto:delm...@ht.sakura.ne.jp
この教科書、やってられないですね。
TACという資格学校が発行している、C言語の教科書です。
大御所が発行している基本情報処理の教科書なので、安心しきっていました。
void main(void){} に関する注意書きも見当たらないです。
こんな間違いがあるんですね。
IIJIMA Hiromitsu wrote:
> いいじまです。
(以下、略)
btohmatu <btoh...@yahoo.co.jp> wrote in
message <3DB0100E...@yahoo.co.jp>:
> gccで奇本情報処理のC言語の勉強をしています。
こんな…
> 参考書には
>
> void main(void)
~(snip)~
> などと書いてあるのですが、
…ことが書いてある様では、正に“奇本”ですね。捨ててしまいま
しょう :-p
> なんとなく気持ち悪いので原因がわかる方がいらしたらお願いします。
gcc のメッセージ通り、main() が int 型ではないからです。且つ、
型を書かないと暗黙で int ですが、きちんと書いた方がいいです。
で、「main() が返す int 値って何?」と思ったら、make から呼ば
れる様なプログラムを書いてみると判ります。
# 昔、一応は道具職人として通っていた人のプログラムを make か
# ら呼んでいて、void main() のせいでヒドい目に遭いました。
EXIT_SUCCESS、EXIT_FAILURE というキーワードで検索を掛けてみて
はいかがでしょうか。
Tabby as くろさわ
ta...@yk.rim.or.jp
http://www.yk.rim.or.jp/‾tabby/
googleで検索すると、すげ―出てくる
C言語講座の奇本ですね。
> > 参考書には
> > void main(void)
> ~(snip)~
> > などと書いてあるのですが、
> …ことが書いてある様では、正に“奇本”ですね。捨ててしまいま
> しょう :-p
--
以上
見て、勝手使って http://rec.ncos.co.jp
"tabe" <ta...@mug.biglobe.ne.jp> wrote in message
news:aopptd$pb4$1...@bgsv5906.tk.mesh.ad.jp...
|
| 田部です。
| 多いねー、これ。
| http://www.catnet.ne.jp/kouno/c_faq/c11.html#15
|
| googleで検索すると、すげ―出てくる
| C言語講座の奇本ですね。
|
|
| > > 参考書には
| > > void main(void)
| > ~(snip)~
| > > などと書いてあるのですが、
| > …ことが書いてある様では、正に“奇本”ですね。捨ててしまいま
| > しょう :-p
void main(void)
{
}
ってマイクロソフトのサンプルプログラムにもありましたよ。
"Yasushi Kondo" <yssk...@mbox.kyoto-inet.or.jp> wrote in message
news:aopqt1$1vv$1...@news.s.kyoto-inet.or.jp...
> | http://www.catnet.ne.jp/kouno/c_faq/c11.html#15
> void main(void)
> {
> }
> ってマイクロソフトのサンプルプログラムにもありましたよ。
#include <Windows.h>とか、
BYTE、WORDのハンガリアン記法とか、
囲い込みがうまいなー、さすが。
一度マ社のコンパイラーを使うと、
他のコンパイラーは使えなくなるわけか。
> > void main(void)
> > {
> > }
> > ってマイクロソフトのサンプルプログラムにもありましたよ。
Microsoft は「main を void 型にするのも認めます、これは仕様です」
と明言しており、規格にも、処理系独自拡張としての void main を
認める規定はない(Java はそういう処理系独自拡張を認めていなくて、
それで Sun と Microsoft がもめごとになりましたが)ので、Microsoft
が書くのは規格上も問題ないのではないかと。
> #include <Windows.h>とか、
> BYTE、WORDのハンガリアン記法とか、
> 囲い込みがうまいなー、さすが。
これは Windows 用にプログラミングする以上は Borland C++Builder
でも gcc(Cygwin/MinGW)でも同じことです。
コンパイラではなくライブラリの問題です。
たしかにこの仕様を作ったのは Microsoft ですが、 Win16 SDK(Soft-
ware Development Kit)のソース互換性も今も引きずっている以上、
ある程度は仕方ないのでは。
> 一度マ社のコンパイラーを使うと、
> 他のコンパイラーは使えなくなるわけか。
正確にいうと、いちど Windows にどっぷり足を踏み入れると他の世界
には戻れなくなる、ですね。かくいう私は、Windows とはいっても
UNIX と共用のコンソールアプリばかり書いているので、プログラムの
中は #ifdef WIN32 とか #ifdef _MSC_VER とかの嵐ですが。
========================================================================
飯嶋 浩光 / でるもんた・いいじま http://www.ht.sakura.ne.jp/~delmonta/
IIJIMA Hiromitsu, aka Delmonta [PC] mailto:delm...@ht.sakura.ne.jp
------【宣伝】----------------------------------------------------------
Emacs の VZ + ATOK + カナ入力化など外道カスタマイズの数々
メールマガジン不定期配信中 ↓バックナンバーはこちらから
http://www.ht.sakura.ne.jp/~delmonta/emacs/
------------------------------------------------------------------------
> この教科書、やってられないですね。
>
> TACという資格学校が発行している、C言語の教科書です。
> 大御所が発行している基本情報処理の教科書なので、安心しきっていました。
> void main(void){} に関する注意書きも見当たらないです。
> こんな間違いがあるんですね。
教科書に限らず、書籍というものは往々にしてそういうものです。
間違いがありうる、ということを前提に読まないといけません。
蛇足
その教科書にはフローチャートが大量にでてくると思います。
自分が書いたプログラムが他の人にも分かりやすいように、
フローチャートを整備しましょう、なんて書いてあると思います。
しかしながら、それはすでに大昔の話なんです。
フローチャートは、読めるようになることは必要ですが、自分で書く
のはたいていの場合、無駄です。
情報処理技術者試験にフローチャートがでてくるから教科書にも出さ
ざるを得ないのですが、実は試験の中身が現場の実状から10年以上も
遅れているんですね。もしくは、10年前の知識のまま頭が止まっている
セソセイが試験の出題をしているか。
ではなぜフローチャートがいけないかというと、フローチャートでは
for 文や while/do-while 文を簡潔に表現できないからです。
フローチャートでは代わりに goto 文を使って表現するしかありません。
goto を無闇に使うのはスパゲッティ・プログラムの温床になるから
よくない、for や while で済むところは for や while で書こう、と
いうのは数十年前から言われていることで(ただし、本当に必要なとき
に適切な方法で使うのはかまいません;それでも最近の言語だと goto
がなくて throw-catch 構文を使わされるものもありますが)、代替の
図記法がいろいろと提唱されてはいますが、いずれも広く支持される
ことなく、結局のところ、人間の言葉(日本語や英語)で要点を記述
することに勝る方法は見つかっていません。昔ならフローチャートは
紙で保管していたんですが、いまはとうぜん電子化するわけで、その
意味でも人間の言葉で書くほうが有利。
また、最近の言語だと、「オブジェクト指向」という概念が広まりつつ
ありますが、これにはフローチャートでは全く対応不能です。
C++、Java、JavaScript、Perl、Delphi、どれをとっても大なり小なり
オブジェクト指向の要素を含んでいます(特に Java や、あるいは
C++ でも MFC を使った Windows プログラミングにはオブジェクト指向
の考え方が必須です)ので、この業界で食べていきたいと考えるなら、
そちらに目をやるべきです。
In message news:3DB0FA45...@ht.sakura.ne.jp
"IIJIMA Hiromitsu" <delm...@ht.sakura.ne.jp> wrote ...
> Microsoft は「main を void 型にするのも認めます、これは仕様です」
一部のコンパイラの例としては、TIのc6xコンパイラ(に付属の
ライブラリ)は void 型が正しかったかと思います。
マニュアルに書いてあったかは憶えてないですが・・・
情報処理試験の教科書を読みながら、僕でも知っている部分がでてくると、
内用が古いと思うことが少なからずあります。インターネットの部分でもいまさ
らISDNなんて、と思いながら憶えました。でもいいじまさんの話を聞いてると、
ISDNはまだましな方みたいですね。
ちょっと引いた立場から、これは試験勉強なんだと思ってがんばります。
もちろん役に立つことも多いのでしょうけど。
今さらながら訂正。
> 規格にも、処理系独自拡張としての void main を
> 認める規定はない
認める規定はない→認めない規定はない
"IIJIMA Hiromitsu" <delm...@ht.sakura.ne.jp> wrote in message
news:3DB0FA45...@ht.sakura.ne.jp...
| いいじまです。
| UNIX と共用のコンソールアプリばかり書いているので、プログラムの
| 中は #ifdef WIN32 とか #ifdef _MSC_VER とかの嵐ですが。
OS依存、ライブラリー依存箇所、共通部分をファイルレベルで分けるって工夫は
無いのですか?
#ifdefの嵐のソースは、見たくない。
> | UNIX と共用のコンソールアプリばかり書いているので、プログラムの
> | 中は #ifdef WIN32 とか #ifdef _MSC_VER とかの嵐ですが。
>
> OS依存、ライブラリー依存箇所、共通部分をファイルレベルで分けるって
> 工夫は無いのですか?
> #ifdefの嵐のソースは、見たくない。
当然それは考えます。最近はひとつのファイルで済むような小物しか書いていな
いのでわざわざ別ファイルに分離していないだけです(^^;)
ただ、できるだけファイルの冒頭に並べるようにはしています。
たとえば、冒頭に
#ifdef WIN32
#include<io.h> // for setmode()
#include<fcntl.h> // for O_BINARY
#define BINMODE(fp) setmode(fileno(fp),O_BINARY)
#else
#define BINMODE(fp) ((void)(fp))
#endif
と書いて、プログラム本体中では単に
BINMODE(stdin);
BINMODE(stdout);
と書くとか。あとは
#include <limits.h>
//「8ビット基調+2の補数表現」でないマシンのことはとりあえず無視
#if INT_MAX==0x7FFFFFFFL // 今のマシンは大体こうですね
typedef unsigned int uint32_t;
#elsif SHORT_MAX==0x7FFFFFFFL // あんまり相手にしたくない(^^;)
typedef unsigned short uint32_t;
#elsif SCHAR_MAX==0x7FFFFFFFL // あんまり相手にしたくない(^^;)
typedef unsigned char uint32_t;
#elsif LONG_MAX==0x7FFFFFFFL // 一昔前の処理系は大体こうですね
typedef unsigned long uint32_t;
#endif
とかも。ちなみに、FreeBSD 4.5 にも VC++4.0 にも BCC5.5 にも stdint.h は
存在しないので、このへんは自前で書くしかない…
この 2 つについては、汎用化したヘッダを作成して LGPL で公開することを
考えています。
☆
ただ、少し前に知人と共謀して某 UNIX 向けコマンドラインツールを Cygwin に
移植したときは、本来なら autoconf を充分に活用すべきなんでしょうけど、
#ifdef WIN32 の羅列という汚いコードで済ませちゃいましたね。「とりあえず
無事に動けばいいや、どうせオリジナルの開発も2年くらい止まってるし」って。
#そのうちドキュメント書いて私のところで公開します(^^;)
btoh...@yahoo.co.jpさん:
> gccで奇本情報処理のC言語の勉強をしています。
「奇本」なんですね :-)
> 参考書には
> void main(void)
それ、その本が嘘っぱちなだけでしょ。Cの規格ではmainはintを返す
ことになってるんじゃないかな。だから
> main(void)
これは「int」を省略してることになるから、gccが正しい。 久野
<ku...@gssm.otsuka.tsukuba.ac.jp> wrote in message
news:aop59i$2n...@utogw.gssm.otsuka.tsukuba.ac.jp...
| 久野です。
|
| btoh...@yahoo.co.jpさん:
| > gccで奇本情報処理のC言語の勉強をしています。
|
| 「奇本」なんですね :-)
|
| > 参考書には
| > void main(void)
|
| それ、その本が嘘っぱちなだけでしょ。Cの規格ではmainはintを返す
| ことになってるんじゃないかな。だから
C++の規格では、void main()は駄目だし、main関数の再帰呼出しも駄目だったは
ず。
C言語の規格では、美学は別として、 void main(void)はOKだったか、規格とし
て決めていなかったような?
うろ覚えです。
> 近藤@うろ覚え
私もうろ覚えですが…というかまともに JIS規格読んでない。
#C Magazine で「ISO/ANSI の規定を日英対訳で読む」という主旨の
#連載があったので、それは読んでいました。
> C++の規格では、void main()は駄目だし、
ふむふむ。
その割には、「main は int だけど、引数なしの return や、return
なしで関数末までいってしまうことも認め、その場合は return 0; と
みなす」とかなんとかいう規定がありませんでしたっけ?
> main関数の再帰呼出しも駄目だったはず。
C 言語だと、「main 関数の*最初の*呼び出しの時には…」ってな
くだりがあろらしいので、そこから「main の再帰呼び出しは可」と
解釈できますね。
> C言語の規格では、美学は別として、 void main(void)はOKだったか、
> 規格として決めていなかったような?
「どこでも公認」ではないでしょうね。
gcc がエラーを吐くってことから推測すると。
ただ、特に禁止する条項も見あたらなかったように思います。
int 以外の型で main を定義することについては処理系定義では
ないかと思います。
> Cの規格ではmainはintを返すことになってる
と, 私も思います.
Freestanding environment での startup はどんな名前でも型でもいいのです
が, Hosted environment では main の戻り値は int を返すよう定義されなけ
ればならない (shall be) とあります.
# 引数に付いては実装依存の道が残っていると思いますが (env[] とか).
--
Kazuo Fox Dohzono / doh...@hf.rim.or.jp
を、堂園さんは
返り値の型がintでかつ
(引数なし or 2引数 or equivalent or 何らかの処理系定義の形) ...(1)
と解釈したわけですが、私は
返り値の型がintでかつ(引数なし or 2引数 or equivalent)
or
何らかの処理系定義の形
だと思います。
わざわざ最後のorの前に;がついているのは、優先順位が変わるからでしょう。
(「又は」と「若しくは」みたいなもの?)
堂園さんの解釈が正しければ、
返り値の型はintまたはそれとequivalentでかつ、
(引数なし or 2引数 or equivalent or 何らかの処理系定義の形)
と書いてあるはずではないでしょうか。
「or equivalent;」のところについている脚注9に
Thus, int can be replaced by a typedef name defined as int, or
the type of argv can be written as char ** argv, and so on.
とありますが、ここで「int」はmainの返り値の型とargcの型の両方を指して
いると解釈するのが自然だと思います。
つまり、
typedef int my_int;
があるとき、
int main(my_int argc, char *argv[]) { /* (A) */ }
とか
my_int main(int argc, char *argv[]) { /* (B) */ }
は許される。
ところが、堂園さんの解釈(1)では、処理系定義の引数型を用いたときに限って、
返り値の型にtypedef名が許されないことになります。これはなんか変でしょ
う。(それとも、上の(A)は許されるが、(B)は許されない? それも変でしょう。)
また、5.1.2.2.3には「もしmainの返り値の型がintとcompatibleでないとき、
ホスト環境に返される終了ステータスはunspecified」だとあります。「shall」
で要求されたことを守らないとunspecifiedどころか未定義動作のはずです。
IIJIMA Hiromitsu <delm...@ht.sakura.ne.jp> writes:
> > C++の規格では、void main()は駄目だし、
>
> ふむふむ。
> その割には、「main は int だけど、引数なしの return や、return
> なしで関数末までいってしまうことも認め、その場合は return 0; と
> みなす」とかなんとかいう規定がありませんでしたっけ?
C99では、もしmainの返り値の型がintとcompatibleで、return文を実行せずに
mainの終りの}に達したら0が返るとあります(5.1.2.2.3)。
(うーん、知らんかった。なんてキタナイ仕様だ。私のまわりには、この仕様
を守ってるCコンパイラはないみたいです。たいてい0でない値が何か返る。こ
んなの守らんでも良い気がする。)
mainの返り値の型がintの時、式なしのreturn文はダメです。
> > main関数の再帰呼出しも駄目だったはず。
>
> C 言語だと、「main 関数の*最初の*呼び出しの時には…」ってな
> くだりがあろらしいので、そこから「main の再帰呼び出しは可」と
> 解釈できますね。
initial call to the main functionという言い方がたしかに5.1.2.2.3に出て
きます。少なくとも禁じてはいないでしょう。C++で禁止している理由は何で
すかね? manglingした結果をどうするかとか、external変数やstatic変数の
コンストラクタ呼び出しがどうなるか、とか?
> > C言語の規格では、美学は別として、 void main(void)はOKだったか、
> > 規格として決めていなかったような?
>
> 「どこでも公認」ではないでしょうね。
> gcc がエラーを吐くってことから推測すると。
>
> ただ、特に禁止する条項も見あたらなかったように思います。
> int 以外の型で main を定義することについては処理系定義では
> ないかと思います。
この投稿の頭で述べた通り、処理系定義の拡張としてはアリです。
もちろん、プログラム側でそれを利用するとポータブルでは無くなりますが。
前田敦司
> 処理系定義の引数型を用いたときに限って、返り値の型にtypedef名が許さ
> れない
確かに変ですね. 撤回しておきます.
つまり処理系依存でない書き方は
int main (void) { /* ... */ }
int main (int ac, char *av[]) { /* ... */ }
の二通り (同じ意味のものを含む) で, 他の書き方は処理系依存ということで
すね (当然 char *env[] とかも).
>IIJIMA Hiromitsu <delm...@ht.sakura.ne.jp> writes:
>>In article <ap0ec2$27fq$1...@news.s.kyoto-inet.or.jp>,
>> "Yasushi Kondo" <yssk...@mbox.kyoto-inet.or.jp> writes:
>> > C++の規格では、void main()は駄目だし、
「駄目」の意味がはっきりしませんが、C++1998 では、
An implementation shall not predefine the main function.
This function shall not be overloaded. It shall have a
return type of int, but otherwise its type is
implementation-defined.
とあるので、「すべての規格準拠処理系で void main() を使えない」
わけではないでしょう。
>> その割には、「main は int だけど、引数なしの return や、return
>> なしで関数末までいってしまうことも認め、その場合は return 0; と
>> みなす」とかなんとかいう規定がありませんでしたっけ?
>C99では、もしmainの返り値の型がintとcompatibleで、return文を実行せずに
>mainの終りの}に達したら0が返るとあります(5.1.2.2.3)。
C++98 も同様(というより、C++98 の規定が C99 に採り入れられた?)
で、
If control reaches the end of main without encountering a
return statement, the effect is that of executing
return 0;
と規定されています。
>(うーん、知らんかった。なんてキタナイ仕様だ。私のまわりには、この仕様
>を守ってるCコンパイラはないみたいです。たいてい0でない値が何か返る。こ
>んなの守らんでも良い気がする。)
C99 準拠の処理系なら、0 を返さなければなりませんね。gcc でも、
% echo 'main(){}f(){}' >x.c; gcc -std=c99 -S x.c; cat x.s
.file "x.c"
.version "01.01"
gcc2_compiled.:
.text
.align 4
.globl main
.type main,@function
main:
pushl %ebp
movl %esp, %ebp
movl 0, %eax
popl %ebp
ret
.Lfe1:
.size main,.Lfe1-main
.align 4
.globl f
.type f,@function
f:
pushl %ebp
movl %esp, %ebp
popl %ebp
ret
.Lfe2:
.size f,.Lfe2-f
.ident "GCC: (GNU) 2.96 20000731 (Red Hat Linux 7.3 2.96-110)"
となります。
>mainの返り値の型がintの時、式なしのreturn文はダメです。
C++ も、
A return statement without an expression can be used only in
function that do not return a value, that is, a function
with the return type void, a constructor, or a destructor.
という規定があります。
--
片山@PFU
"MAEDA Atusi" <ma...@cc.tsukuba.ac.jp> wrote in message
news:m31y6j4...@maedapc.cc.tsukuba.ac.jp...
> It shall be defined with a return type of int and with no parameters
> ... or with two parameters ... or equivalent; or in some other
> implementation-defined manner. (C99, 5.1.2.2.1)
>
> を、堂園さんは
>
> 返り値の型がintでかつ
> (引数なし or 2引数 or equivalent or 何らかの処理系定義の形) ...(1)
>
> と解釈したわけですが、私は
>
> 返り値の型がintでかつ(引数なし or 2引数 or equivalent)
> or
> 何らかの処理系定義の形
>
> だと思います。
>
堂園さんのあの数行の記事から,上のような解釈の違いがなぜ分かったんだろうと不
思議に思ってますが。堂園さん自身が認めているのだから間違いないことだと思いま
すが。
で,前田さんの書かれている解釈だと,例えば
struct foo { int i; double d; } main (double argc, struct foo argv)
みたいなのも(もちろん,void main(void) も同様ですが。)OKのように思える
のですが,私の読み方が変なのでしょうか。何らかの処理系定義の形は,引数に関し
て言っているのではないでしょうか。
(だので,堂園さんの言う実装依存の意味が処理系定義と同義とすれば,別に変には
感じなかったのですが。)
> わざわざ最後のorの前に;がついているのは、優先順位が変わるからでしょう。
> (「又は」と「若しくは」みたいなもの?)
>
;は hosted environment で implementation-defined とそうでないケースを分
けるために区切りを入れたのではと思っていますが,自身なしです。
--
******************************
keizi kounoike
******************************
> 堂園さんのあの数行の記事から,上のような解釈の違いがなぜ分かったんだろうと不
> 思議に思ってますが。堂園さん自身が認めているのだから間違いないことだと思いま
> すが。
私も同じところで解釈に迷ったからです:-)。
> で,前田さんの書かれている解釈だと,例えば
>
> struct foo { int i; double d; } main (double argc, struct foo argv)
>
> みたいなのも(もちろん,void main(void) も同様ですが。)OKのように思える
> のですが,私の読み方が変なのでしょうか。何らかの処理系定義の形は,引数に関し
> て言っているのではないでしょうか。
処理系が、「上のようなmainの型を受け入れる」と文書で定義してあれば、そ
の処理系では上はOKだ(conforming programだ)というのが私の解釈です。
void main(void)も同様で、そういう拡張をした処理系も許されます。
先の記事は我ながらわかりづらかったので、もう1回 別の書き方で説明します
と、
(根拠1)
> > It shall be defined with a return type of int and with no parameters
> > ... or with two parameters ... or equivalent; or in some other
> > implementation-defined manner. (C99, 5.1.2.2.1)
これを、
1.返り値の型がintで、引数無し
2.返り値の型がintで、引数がint argcとchar *arv[]
3.上のどちらかとequivalent(typedef名でも良い)
4.返り値の型がintで、引数が何らかの処理系定義の形
のいずれか
と解釈すると、4の時だけは返り値の型にtypedef名が使えないという変なこと
になります。あるいは、
1.返り値の型がintで、引数無し
2.返り値の型がintで、引数がint argcとchar *arv[]
3.返り値の型がintで、引数が上のどちらかとequivalent(typedef名でも良い)
4.返り値の型がintで、引数が何らかの処理系定義の形
のいずれか
と解釈すると、引数にはtypedef名が使えるのに返り値には使えないという変
なことになります。なので
1.返り値の型がintで、引数無し
2.返り値の型がintで、引数がint argcとchar *arv[]
3.上のどちらかとequivalent(typedef名でも良い)
4.何らかの処理系定義の形
のいずれか
という解釈を私はとります。
(根拠2)
返り値の型がintでないと正しいプログラムでない(undefined behaviorである)
なら、なぜ次の節で「返り値がintのときには」「返り値がintでないときには」
とわざわざ場合わけして述べているのでしょうか。正しくないプログラムの正
しい動作(?)を規定しようとするなんておかしいでしょう。
> > わざわざ最後のorの前に;がついているのは、優先順位が変わるからでしょう。
> > (「又は」と「若しくは」みたいなもの?)
> >
>
> ;は hosted environment で implementation-defined とそうでないケースを分
> けるために区切りを入れたのではと思っていますが,自身なしです。
こっちは根拠というには弱いと私も思っています。
-=-=-=-=-=-=-=-=-=-=-=-=
なお、C FAQ(http://www.faqs.org/faqs/C-faq/faq/)では
「mainの型はintと宣言しなければならない」(11.12b)
「void main(void)と書いてある本は誤りだ」(11.15)
と書いてあります。
これは、同じく11.12aに、
「mainの正しい宣言はint main()かint main(void)かint main(int argc,
char *argv[])かのいずれかだ(引数の名前は違っても良い)」
とあるのを見ても分かる通り移植性のあるプログラムとして正しいかどうかを
述べているわけで、
「mainの型はintと宣言しなければstrictly conformingではない」
「特定の処理系に依存すべきでない本でvoid main(void)と書くのは誤りだ」
という意味でしょう。
前田敦司
"MAEDA Atusi" <ma...@cc.tsukuba.ac.jp> wrote in message
news:m3n0p5l...@maedapc.cc.tsukuba.ac.jp...
> <koun...@mbh.nifty.com> writes:
> (根拠2)
> 返り値の型がintでないと正しいプログラムでない(undefined behaviorである)
> なら、なぜ次の節で「返り値がintのときには」「返り値がintでないときには」
> とわざわざ場合わけして述べているのでしょうか。正しくないプログラムの正
> しい動作(?)を規定しようとするなんておかしいでしょう。
前田さんの解釈が正しいのが,これでやっと分かりました。
ところで,Hosted environment で implementation-defined の場合,
その処理系において
プログラムAで例えば
int main(void){
...........
}
プログラムBでは
void main(void){
...........
}
と書いたとき両方とも正常に動作すると解釈してもよいのでしょうか。
> ところで,Hosted environment で implementation-defined の場合,
> その処理系において
> プログラムAで例えば
>
> int main(void){
> ...........
> }
>
> プログラムBでは
> void main(void){
> ...........
> }
>
> と書いたとき両方とも正常に動作すると解釈してもよいのでしょうか。
実行されるところまでは同じでしょうね。処理系が何か決めているかもしれま
せんが(たとえば、後者だとリンカにこういうオプションをつけろとか)。
後者がホスト環境にどういう終了ステータスを返すかはunspecified(規格では
規定しない)です。
前田敦司
"MAEDA Atusi" <ma...@cc.tsukuba.ac.jp> wrote in message
news:m365vql...@maedapc.cc.tsukuba.ac.jp...
> <koun...@mbh.nifty.com> writes:
>
> > ところで,Hosted environment で implementation-defined の場合,
> 後者がホスト環境にどういう終了ステータスを返すかはunspecified(規格では
> 規定しない)です。
>
つまらない質問ですが,
A conforming hosted implementation shall accept any strictly conforming
program.と言う中で implementation-defined した場合 unspecified は,明確に
なるとのでは。
そうしたとき,プログラムAもBもきっちりと受け付けられるのかなと疑問に思った
次第です。
> > > ところで,Hosted environment で implementation-defined の場合,
> > 後者がホスト環境にどういう終了ステータスを返すかはunspecified(規格では
> > 規定しない)です。
> >
>
> つまらない質問ですが,
> A conforming hosted implementation shall accept any strictly conforming
> program.と言う中で implementation-defined した場合 unspecified は,明確に
> なるとのでは。
ううう、ちょっと意味が分かりません。strictly conforming programは
implementation-definedな振る舞いに依存しないものです。
"strictly conforming program" 規格で規定された言語機能とライブラリだけ
を用い、出力がunspecifiedやundefinedやimplementation-definedな振る舞い
に依存せず、規格で決められた『最小限この規模のプログラムは扱えなければ
ならない』という限度を越えない規模のプログラム
"conforming hosted implementation" conforming implemenationの一種で、
全てのstrictly conforming programを受け付ける処理系
"unspecified behavior" どう振る舞うか2つ以上の可能性が規格で示されてお
り、どの選択肢を選ぶかについて何も要求されていないこと
"implementation-defined behavior" unspecified behaviorのうち、どの選択
肢を選んだか各処理系が文書化しておくもの
"conforming program" あるconforming implemenationが受け付けるプログラ
ム
です。
> そうしたとき,プログラムAもBもきっちりと受け付けられるのかなと疑問に思った
> 次第です。
mainの書き方以外は両者とも全てstrictly conformingだとすると、
プログラムAはstrictly conforming programです。全てのconforming hosted
implementationで受け付けられます。
プログラムBは、特定の処理系においてはconforming programかもしれません
がstrictly conforming programではありません。他の処理系で動く保証はあ
りません。
プログラムBを受け付けるconforming hosted implemenationがあったと仮定
すると、プログラムAも受け付けられます。
前田敦司
"MAEDA Atusi" <ma...@cc.tsukuba.ac.jp> wrote in message
news:m3adkzj...@maedapc.cc.tsukuba.ac.jp...
> <koun...@mbh.nifty.com> writes:
> ううう、ちょっと意味が分かりません。strictly conforming programは
> implementation-definedな振る舞いに依存しないものです。
すいません。途中をだいぶ削った分かり難い文で。
>
> プログラムBを受け付けるconforming hosted implemenationがあったと仮定
> すると、プログラムAも受け付けられます。
確認したかったところは,この箇所なんです。で,すっきりしました。