作者tropical72 (藍影)
看板C_and_CPP
標題[問題] main 前執行之函式?(已解決)
時間Sat Sep 3 03:32:35 2011
這是在 vc 2008 trace 時, 不小心發現的問題,
trace 時, 由 F11 trace 一些 source code ,
雖看得很吃力, 但仍硬看下去, 看到後來有點懷疑,
應該是有東西要在進入 main 之前先執行過才對,
想請教, vc 是否有方法, 能在進入 main 前, 先執行過某個函式 ?
謝謝各位。
問題已解決, 下述供參考。(還真是有趣的問題啊!!)
---
一開始一直試都不成功,原因在於 Visual C++ .c 不支援 C99,
改 .cpp 之後就過了,一開始查 msdn ,查到這份網頁
http://msdn.microsoft.com/en-us/library/bb918180.aspx
看完第一個 global variable initialize 後,裡面說明提到
According to the C/C++ standard, func() must be called before main() is
executed. But who calls it?
( M$ 真是自打嘴巴,明明說標準可以這麼做,偏偏 .c 連這點都不支援)
這部份可能查 C99 會有更多的說明, 但 M$ 這份我覺得寫得還不錯。
基於上述,第一份 code 試作
// only for cpp
#include <stdio.h>
#include <stdlib.h>
int* Alloc10(){ return (int*)malloc(sizeof(int)*10);}
int *p = Alloc10();
int main()
{
int i;
for(i=0; i!=10; ++i) p[i]=i;
for(i=0; i!=10; ++i) printf("%d ", p[i]);
free(p);
return 0;
}
----
以下東西,對 Visual C++ 不感興趣可跳過。
在剛上面那個連結裡面,原文提及了
But who calls it?
又有幾個關鍵字 : .CRT$XCU .CRT$XCA .CRT$XCZ ,
最後連到這個網站
http://zh-cn.w3support.net/index.php?db=so&id=728939
原來是在搞 #pragma section, 有興趣連進去看 section 在幹嘛
http://msdn.microsoft.com/en-us/library/sf9b18xk(v=vs.80).aspx
由於嫌對岸網站寫得太... 文言文,想說自己把能改的都改看看
#include <stdio.h>
#pragma section(".CRT$XIC1",long,read)
// ==========================================
void before_main(void); /* function declare */
typedef void ( *pfpuc)(void); /* function pointer */
#define _CRTALLOC(x) __declspec(allocate(x))
/* set function before main */
_CRTALLOC(".CRT$XIC1") static pfpuc pinit1 = before_main;
// ==========================================
int z;
void before_main(void)
{
z = 100;
}
int main(void)
{
printf("Some code before main!\n");
printf("z = %d\n", z);
printf("End!\n");
return 0;
}
嗯, 一切都正常執行,只是不確定有沒有拿掉不該拿的就是了。
---
關於 debug 部份,可能也是我技巧沒很好 (最近 VS 2008 Debugger 常被我搞掛要重開)
但若照 MSDN 上對於 section header 說明,
global variable initialize 之部份應該完全 trace 不到,
以上述的 *p = Alloc10(); 而言,按下 F11 就直接進到 main 了,
完全沒機會看到那段 ( Debug 從 main 開始 trace 也算合理吧 ) 。
而用 #pragma section, 那又更特別了,按下 F11 ,程式直接結束...
至於 e 大提到 dll 的話, 嗯, 目前我也不會追, 連導出函式名都不會。
--
YouLoveMe() ? LetItBe() : LetMeFree();
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 180.177.78.41
推 ericinttu:哪一種C++ project? 09/03 03:37
→ tropical72:普通 win32,console mode,再補一下,是沒 malloc,最後可 09/03 03:38
→ tropical72:正常 free 掉,所以認為應是在進入前就有 malloc.. 09/03 03:39
推 ericinttu:我只知道去看call stack, 誰call 了誰. XD 09/03 03:47
→ tropical72:trace 不到.. 09/03 03:59
→ xatier:global 變數的初始化XD 09/03 04:00
推 ericinttu:trace 不到是指什麼? 感覺是有用DLL才追不進去? 09/03 04:09
※ 編輯: tropical72 來自: 180.177.78.41 (09/03 05:03)
推 ericinttu:請忽略上一句關於DLL. 另外, 你有設中斷點(紅點)嗎? 09/03 05:02
→ tropical72:狂設中斷點,其實那設心安而已,用F11是進入函式逐步執行 09/03 05:04
→ tropical72:VS 用的 rand() 公式也是這樣被 F11 出來.. 09/03 05:05
推 ericinttu:第一份code, Alloc10() 跟 main()都會進去. 09/03 05:06
→ ericinttu:第2份code, before_main()會進去, main()不會進去. 09/03 05:07
→ ericinttu:至於為什麼, 我太弱不知道, 留給強者回答 XD 09/03 05:08
→ tropical72:!! 是我 setting 有問題嗎?我再研究一下,感謝 !! 09/03 05:08
→ ericinttu:要去研究一下 crt0dat.c 裡面做了什麼事情. 09/03 05:09
→ ericinttu:對了, 我是用 VS2010 版 (不知道有沒有差,先說明一下) 09/03 05:10
→ tropical72:我補一下好了,如果斷點是設成 Alloc10那裡,進得去, 09/03 05:11
→ tropical72:但一般 debug trace 時,怎會知道斷點要設在那 func ? 09/03 05:12
→ tropical72:(當然現在是知道直接先查 global variable 是真的) 09/03 05:13
推 ericinttu:你會這樣trace, 應該是有一些東西是依附在win32 console 09/03 05:20
→ ericinttu:平台上面. 我對那邊沒經驗也沒看過有人把自己寫的東西架 09/03 05:21
→ ericinttu:構在win32 console上, 假如是這樣的方式, 應該會需要了 09/03 05:22
→ ericinttu:解 crtexe.c 與 crt0dat.c 做了什麼事. 09/03 05:22
→ ericinttu:用 call stack 也可以找到一些線索. 09/03 05:23
→ tropical72:嗯嗯,謝謝e大,這陣子有空再摸摸那兩隻 .c, 感謝. 09/03 05:26
推 purpose:w3support 盡貼一些 stackoverflow 的翻譯內容 09/03 21:23
→ tropical72:p大沒說真沒注意到 stackoverflow 也有此文。 09/03 22:02