今回のトピックは試験問題が遡上にあがっています。
試験というからには前提となる「ルール」があるはずで
日本国の教員資格の試験であれば、それは JIS 規格であるべきでしょう。
gcc とか (以下略) の個別の実装の話を出すのは
(カルマを減らす or ちゃちゃいれ or 他人をおちょくる or so on が目的でなければ)
そろそろ潮時かな~と愚考する次第です。
# もっともこの話題の発端は Oliver 氏の伝えるところの
# 教授氏のmath-out [tuxedo.org]な話から始まっているので
# 結局はこの教授氏を説き伏せるのにどちら (規格 or 実装) が
# 有効かという話に帰結したりするのかも。
みんなで void main (スコア:0)
教科書にそう書いてあるから。
もう、どうにでもなれって、感じですね。
情報処理学会のどこかの部会かなんかが出した、
情報教育の教科書でも、void main ってなってますよ。
動きゃいいんじゃないの?
もう、知らんって感じ。
Re:みんなで void main (スコア:2, 興味深い)
メソッドは副作用があり、戻り値がない。エラーはExceptionなどの別の方法で通知。
ファクション(関数)は副作用がなく、戻り値がある。戻り値の算出に引数以外に依存すべきではない。
というのが「正しい」姿だからだそうだ。で、mainはメソッドなので、voidでなければいけないそうだ (うちのオブジェクト指向論教授談)。
exit(1)の1ってmain()の戻り値やん、と反論したら、いやー
returnじゃないから
Re:みんなで void main (スコア:1)
UNIX 系の C の場合,そもそも main() って,なんとかcrtかんとか.o というスタートアップルーチン(?)からコールしている関数に過ぎないのだけれど.というわけで,引数と戻り値については,単になんとかcrtかんとか.o との摺合わせ,という話になるのではないか,と思います.
あ
規格で決まってるの (スコア:0)
規格は規格,実装は実装 (スコア:1)
サブジェクトの通り :-)
ま,この試験の場合は規格の方に従うべきで,特定の実装に依存するのは好ましくないとは思いますが. ま,UNIX 系 OS ではそういう仕組みになってることが多いので,void main(void) でも矛盾しない実行ファイルが生成できる,というだけの話.
実装なら、現実の実装 (スコア:0)
あくまでも。
そもそも、最初のC言語にvoidはないし。
Re:実装なら、現実の実装 (スコア:1)
----------
#include <unistd.h>
void Main ( void );
void _start (int argc, char *argv[])
{
write ( 1, "_start\n", 7 );
Main();
_exit ( 0 );
}
void Main ( void )
{
write ( 1, "hello,world\n", 12 );
}
----------
(1)Linux において,このプログラムを
$ gcc -Wall hello.c -S -o hello1.s
$ gcc hello1.s -c
$ ld hello1.o -Bstatic -lc -o hello
と,コンパイ
そんなこと聞いてないんだけど (スコア:0)
char main[] = { 機械語... };
だって、多くのマシン/OSで動くでしょ。
DOSでも動くし。
まさにこのコード(Re:そんなこと聞いてないんだけど (スコア:2)
...というだけではナンなので。 :-)
今回のトピックは試験問題が遡上にあがっています。 試験というからには前提となる「ルール」があるはずで 日本国の教員資格の試験であれば、それは JIS 規格であるべきでしょう。 gcc とか (以下略) の個別の実装の話を出すのは (カルマを減らす or ちゃちゃいれ or 他人をおちょくる or so on が目的でなければ) そろそろ潮時かな~と愚考する次第です。
# もっともこの話題の発端は Oliver 氏の伝えるところの
# 教授氏のmath-out [tuxedo.org]な話から始まっているので
# 結局はこの教授氏を説き伏せるのにどちら (規格 or 実装) が
# 有効かという話に帰結したりするのかも。
Re:そんなこと聞いてないんだけど (スコア:1)
「現実の実装」の例の1つを示したつもりだったのだけれど,何を聞こうとしていたのでしょうか?
機械語…の部分が,値を返さずに return するプログラムだとしても,これでは,「main が値を返さないルーチン」として矛盾の無い実行プログラムを生成することはできません. 普通にコンパイルした場合,コンパイラの標準のスタートアップルーチンがリンクされるので,呼び出し側との整合性が取れません. その結果,void main(void) と宣言してコンパイル・実行した時と同じように,「終了ステータスにゴミが返される」という現象が生じるでしょう. そもそも,「動く動かない」だけのの問題だったら,スタートアップルーチンがうんぬん,と言い出さなくても void main(void) でも動きますね.
なんか話がそれてしまってる気もするので,今までのところをまとめてみると
普通はここでシェアードライブラリの実行時リンクと,カーネルと main() のインターフェースを行っている
どっちも (スコア:0)
どっちも、規格にない「ブラックボックス」部分
の実装を利用しているだけでしょう。
ブラックボックスの部分の機能に依存したり、
ブラックボックス自体を書き換えたりして、
動くって言っても、そりゃ動くでしょうけど。
スタートアップルーチンを書き換えちゃうのが、
現実の実装にのっ
Re:どっちも (スコア:1)
そのとおり. C 言語の規格においては,int main(int,char**) の呼び出し元については何も規定されていません. ということは,int main(int,char**) というのは,規格の内と外の境界線に接しているわけです. 現実の実装で int main(int,char**) がどのように反映されているか見てみるには,その境界の外に踏み出す必要があるわけです.
これもそのとおり. main をマシン語で直書きしても,呼び出し元と呼び出し先の引数と戻り値の受渡しについては,状況はなにも変わりません. void main(void) を,このインターフェースに矛盾が生じないよう実装するには,前に書いたように呼び出し元に手を入れる必要があります. つまり,標準的な実装ではないわけです.
で,話をこのスレッドの私の最初の書き込みに戻すと,「main() の引数と戻り値の問題は,実装の面から見ると,スタートアップルーチンとのインターフェースの問題である」というあたりは御理解いただけたようですね. あと,「実際にはどうなってるんだろ.知りたいな」と横から眺めてる,スケベ心満載の御仁にも満足いただけたと思います :-)