アカウント名:
パスワード:
UNIX 系の C の場合,そもそも main() って,なんとかcrtかんとか.o というスタートアップルーチン(?)からコールしている関数に過ぎないのだけれど.というわけで,引数と戻り値については,単になんとかcrtかんとか.o との摺合わせ,という話になるのではないか,と思います.
あ
サブジェクトの通り :-)
ま,この試験の場合は規格の方に従うべきで,特定の実装に依存するのは好ましくないとは思いますが. ま,UNIX 系 OS ではそういう仕組みになってることが多いので,void main(void) でも矛盾しない実行ファイルが生成できる,というだけの話.
「現実の実装」の例の1つを示したつもりだったのだけれど,何を聞こうとしていたのでしょうか?
char main[] = { 機械語... };
機械語…の部分が,値を返さずに return するプログラムだとしても,これでは,「main が値を返さないルーチン」として矛盾の無い実行プログラムを生成することはできません. 普通にコンパイルした場合,コンパイラの標準のスタートアップルーチンがリンクされるので,呼び出し側との整合性が取れません. その結果,void main(void) と宣言してコンパイル・実行した時と同じように,「終了ステータスにゴミが返される」という
どっちも、規格にない「ブラックボックス」部分 の実装を利用しているだけでしょう。 ブラックボックスの部分の機能に依存したり、 ブラックボックス自体を書き換えたりして、 動くって言っても、そりゃ動くでしょうけど。
そのとおり. C 言語の規格においては,int main(int,char**) の呼び出し元については何も規定されていません. ということは,int main(int,char**) というのは,規格の内と外の境界線に接しているわけです. 現実の実装で int main(int,char**) がどのように反映されているか見てみるには,その境界の外に踏み出す必要があるわけです.
なに? return値が保障されない? そりゃ、return文相当のものを書かない プログラマがいけないんでしょう。 main() { printf("Hello world\n"); } と同じ。
これもそのとおり. main をマシン語で直書きしても,呼び出し元と呼び出し先の引数と戻り値の受渡しについては,状況はなにも変わりません. void main(void) を,このインターフェースに矛盾が生じないよう実装するには,前に書いたように呼び出し元に手を入れる必要があります. つまり,標準的な実装ではないわけです.
で,話をこのスレッドの私の最初の書き込みに戻すと,「main() の引数と戻り値の問題は,実装の面から見ると,スタートアップルーチンとのインターフェースの問題である」というあたりは御理解いただけたようですね. あと,「実際にはどうなってるんだろ.知りたいな」と横から眺めてる,スケベ心満載の御仁にも満足いただけたと思います :-)
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
一つのことを行い、またそれをうまくやるプログラムを書け -- Malcolm Douglas McIlroy
みんなで 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:そんなこと聞いてないんだけど (スコア:1)
「現実の実装」の例の1つを示したつもりだったのだけれど,何を聞こうとしていたのでしょうか?
機械語…の部分が,値を返さずに return するプログラムだとしても,これでは,「main が値を返さないルーチン」として矛盾の無い実行プログラムを生成することはできません. 普通にコンパイルした場合,コンパイラの標準のスタートアップルーチンがリンクされるので,呼び出し側との整合性が取れません. その結果,void main(void) と宣言してコンパイル・実行した時と同じように,「終了ステータスにゴミが返される」という
どっちも (スコア:0)
どっちも、規格にない「ブラックボックス」部分
の実装を利用しているだけでしょう。
ブラックボックスの部分の機能に依存したり、
ブラックボックス自体を書き換えたりして、
動くって言っても、そりゃ動くでしょうけど。
スタートアップルーチンを書き換えちゃうのが、
現実の実装にのっとっているのなら、
mainをchar配列にしちゃうのだって、
現実の実装にのっとって動きますよ。
なに? return値が保障されない?
そりゃ、return文相当のものを書かない
プログラマがいけないんでしょう。
main() { printf("Hello world\n"); } と同じ。
Re:どっちも (スコア:1)
そのとおり. C 言語の規格においては,int main(int,char**) の呼び出し元については何も規定されていません. ということは,int main(int,char**) というのは,規格の内と外の境界線に接しているわけです. 現実の実装で int main(int,char**) がどのように反映されているか見てみるには,その境界の外に踏み出す必要があるわけです.
これもそのとおり. main をマシン語で直書きしても,呼び出し元と呼び出し先の引数と戻り値の受渡しについては,状況はなにも変わりません. void main(void) を,このインターフェースに矛盾が生じないよう実装するには,前に書いたように呼び出し元に手を入れる必要があります. つまり,標準的な実装ではないわけです.
で,話をこのスレッドの私の最初の書き込みに戻すと,「main() の引数と戻り値の問題は,実装の面から見ると,スタートアップルーチンとのインターフェースの問題である」というあたりは御理解いただけたようですね. あと,「実際にはどうなってるんだろ.知りたいな」と横から眺めてる,スケベ心満載の御仁にも満足いただけたと思います :-)