順便來解釋一下為什麼 main() 最好宣告為 int () 吧.
main() 並不是一個程式最早的進入點.
在 main() 之前, compiler 會塞入一段 startup code.
這一段碼通常是用來準備程式該跑的環境.
比方設定暫存器, 堆疊, 準備一些資料初值等等的雜事.
定完了才真正進入 main().
這一段 startup code 通常是根據 int main() 來寫的.
void () 的函式, 呼叫和返回程序和一般函式有可能不同.
如果把 main() 宣告成 void ().
在 startup code 呼叫 main() 的過程當中也許會出錯.
當然這情形不是一定發生.
只不過要是某天出問題, 說不定很難找出癥結. :)
可以翻一下那些所謂 bible 級的書.
裡頭的 main() 都是清一色的 int ().
寧可最後塞一行沒什麼意義的 return.
我知道很多書上會用 void () 的方式來宣告 main().
不過這是有問題的.
而且不只是哲學、邏輯上的問題, 它是蠻實際的問題. :)
--
小魚轉來的
有沒有人知道「startup」的細節呢?
--
Much ado about nothing.
--
※ Origin: 程式設計樂園 ◆ From: r215-77.D5-214.ncu.edu.tw
> -------------------------------------------------------------------------- <
發信人: Philosopher.bbs@cszone.cc.ntu.edu.tw (色不異空|空不異色), 看板: C_and_CPP
標 題: Re: [C]關於進入 main() 之前..
發信站: 程式設計樂園(CSZone) (Mon Nov 23 14:17:46 1998)
轉信站: Ptt!CSZoneNews!CSZone
※ 引述《mhhsu (Set Limitation )》之銘言:
: 我知道很多書上會用 void () 的方式來宣告 main().
: 不過這是有問題的.
: 而且不只是哲學、邏輯上的問題, 它是蠻實際的問題. :)
其實如果會有問題, 只是'可能'該程式的返回值變成無法預測的值 :)
因為 C Run-time library 不會去管 main 的 return 是什麼,
而在大部分的 calling convention 下, return 值都放在某個 register
for x86, its AX/EAX
for ARM, its a1
所以理論上通常不會造成什麼影響......
: 有沒有人知道「startup」的細節呢?
通常 startup 做的就是 initialize data segment, clear all memory to
zero in uninitialzed data segment (BSS), set up stack, jump to main.
( 這是 C 的 startup )
C++ 的 startup 我猜還要加上自動找出 global objects, 並且去 run
每個 global object 的 constructor
--
這是一個專門討論 programming 和 computer science 的 BBS
這裡有人工智慧,類神經網路,即時作業系統,各式Windows programming的專版
在 cszone.cc.ntu.edu.tw , login:bbs , port 3001~3005
期待你的加入, 豐富這裡的園地
--
※ Origin: 程式設計樂園 ◆ From: titan.ee.ntu.edu.tw
> -------------------------------------------------------------------------- <
發信人: Philosopher.bbs@cszone.cc.ntu.edu.tw (色不異空|空不異色), 看板: C_and_CPP
標 題: Re: [C]關於進入 main() 之前..
發信站: 程式設計樂園(CSZone) (Tue Nov 24 21:53:38 1998)
轉信站: Ptt!CSZoneNews!CSZone
※ 引述《Philosopher (色不異空|空不異色)》之銘言:
: C++ 的 startup 我猜還要加上自動找出 global objects, 並且去 run
: 每個 global object 的 constructor
以下是 GCC 定義的巨集, 用來 initialize global objects
在 main 之前會自動被呼叫
do { ... } while (0) really cool ^_^
#define DO_GLOBAL_CTORS_BODY \
do { \
unsigned long nptrs = (unsigned long) __CTOR_LIST__[0]; \
unsigned i; \
if (nptrs == -1) \
for (nptrs = 0; __CTOR_LIST__[nptrs + 1] != 0; nptrs++); \
for (i = nptrs; i >= 1; i--) \
__CTOR_LIST__[i] (); \
} while (0)
#endif
--
這是一個專門討論 programming 和 computer science 的 BBS
這裡有人工智慧,類神經網路,即時作業系統,各式Windows programming的專版
在 cszone.cc.ntu.edu.tw , login:bbs , port 3001~3005
期待你的加入, 豐富這裡的園地
--
※ Origin: 程式設計樂園 ◆ From: titan.ee.ntu.edu.tw
> -------------------------------------------------------------------------- <
發信人: Philosopher.bbs@cszone.cc.ntu.edu.tw (阿哲), 看板: C_and_CPP
標 題: Re: [C]關於進入 main() 之前..
發信站: 程式設計樂園(CSZone) (Fri Dec 18 15:38:54 1998)
轉信站: Ptt!CSZoneNews!CSZone
關於 djgpp 如何去呼叫 global object 的 constructor 的問題,
我在 djgpp 的 mail archive 找到了答案, 有興趣的人可以參考:
Date: Thu, 10 Jul 1997 14:54:35 +0000
From: Bill Currie <billc@blackmagic.tait.co.nz>
Subject: Re: ctor ?
What happens with .ctor is: gcc places a pointer to either a generated
functions (C++) or a user supplied function using
__attribute__((constructor)) (C) into the .ctor section of the .o file.
In C++, a function declared with __attribute__((constructor)) gets
called by the function generated by gcc. When linking, all the .ctor
sections get concatenated into an array starting at djgpp_first_ctor and
ending just befor djgpp_last_ctor (via the linker script). At startup,
the libc startup code (_main() in _main.c) goes through this array
calling each function in turn. This happens before main is called
(actually, gcc places a call to _main() at the beginning of main(), but
libc calls _main itself (don't know why (dj, can you say why?)) and so
_main() also has a test to see if it has done the .ctor calls yet).
As to why you can't break on f(), I don't know. If it was with the C
code, maybe it's due to the error/warning message you got. For C++, all
I can think of is you have to place a breakpoint on the function before
ANY code is run. Does gdb run all code up to main() on startup?
Also, it's a very similar story for .dtor (but the code for calling the
functions is somewhere in exit(), which (for the proponents of void
main()) gets called immediatly after main returns with main's return
value) but you use `__attribute__((destructor))' to create a .dtorentry.
The order of .ctor and .dtor function calls is determined by the link
order of the .o files they are in. I have no idea wheter .dtor calls
are in the reverse order of .ctor calls or not.
--
※ Origin: 程式設計樂園 ◆ From: hpc.ee.ntu.edu.tw