2012-01-03 180 views
20

在面向對象的語言(C++)中,可以使用全局對象或類靜態對象在main()之前執行代碼,並使其構造函數運行所需的代碼。在main()之前執行代碼()

C有沒有辦法做到這一點?我沒有任何具體的問題,我試圖解決,我只是好奇。這可能有用的一件事是自動初始化一個庫。

+0

http://stackoverflow.com/questions/949890/how-can-i-perform-pre-main-initialization-in-cc-with-avr-gcc – stacker 2012-01-03 14:13:12

+0

@stacker - 您提到的問題是特定於Arduino環境。無論如何,答案可能會有幫助。 – mouviciel 2012-01-03 14:18:01

回答

10

有幾種方法使用__attribute__但這些都是非常具體的你的編譯器和使用這些寫的代碼是而不是真的很便攜。另一方面,C語言不提供任何啓動模塊/庫。

在C中,邏輯上main()是OS調用的第一個函數。但在調用main()之前,OS調用另一個稱爲start-up模塊的函數來設置各種環境變量,初始化(未初始化)的靜態變量,構建堆棧幀(激活記錄)並將堆棧指針初始化爲堆棧區域的開始以及其他在致電main()之前必須完成的任務。

如果你正在編寫嵌入式系統的代碼,那裏沒有或者最小的操作系統來完成上述工作,那麼你應該研究這些依賴於編譯器的選項。除GCC之外,Turbo-C和Microsoft C編譯器提供了在特定硬件機器(如8086機器)中添加代碼的工具。

IOW,啓動模塊不適用於程序員。

+0

錯誤,'main'不是操作系統調用的第一個函數。你聽說過[crt0](https://en.wikipedia.org/wiki/Crt0)嗎? '_start'總是在'main'之前調用,而在Windows中'WinMain'也在main之前調用。 – 2017-05-16 21:34:49

0

您可以初始化全局變量,但不能在這些初始化中調用函數。

1

不,你不能在C中這樣做,而且我會爭辯說,即使在C++中,你也無法得到「在main()之前執行的代碼」。是的,它可能main()之前出現,但main()是程序實際啓動的地方。

現在,您可以初始化值,這是可能的。你也可以有一個預設狀態的變量,但這不是一回事。

+3

根據3.6.2/3(「它應該在第一次使用在同一個翻譯單元中定義的任何函數或對象作爲初始化對象」之前發生),名稱空間範圍與'main'相同TU的對象必須是在'main'的第一個語句之前被初始化,因爲'main' *是同一個TU中的一個函數。該標準並不關心在main函數體內是否有對該init代碼的調用,在任何其他語句之前,或者是否有其他函數執行init,實現在調用main之前調用它。 – 2012-01-03 14:24:38

4

使用gcc,您可以通過使用構造函數屬性(例如,

__attribute__ ((__constructor__)) 
void foo(void) { 
     ... 
} 

這將在main之前調用foo。

注意:這可能不適用於其他編譯器。

13

您可以使用__attribute__ ((constructor))來完成。我用gccclang測試了以下示例。這就是說,它的不是的部分語言。

#include <stdio.h> 

void __attribute__ ((constructor)) premain() 
{ 
    printf("premain()\n"); 
} 

int main(int argc, char *argv[]) 
{ 
    printf("main()\n"); 
    return 0; 
} 

它執行以下操作:

$ ./test 
premain() 
main() 
0

沒有在任何符合標準的方式,但你應該在挖掘時操作系統加載二進制圖像,並調用應用程序的主要功能到底發生了什麼!

0

有一些可移植的方式來指定可以在執行main之後執行的函數。

  1. atexit()

  2. at_quick_exit()

此外,遵循this鏈路和關於各種類型C++初始化的 - 這可能是有用的爲你之前主要執行代碼()被調用。

+0

此外,請遵循此[鏈接](http://en.cppreference.com/w/cpp/language/initialization)以及有關C++中各種類型的初始化 - 這可能對您在main()之前執行代碼很有用調用。 – 2017-05-12 09:50:51

+0

問題是在C語言之前調用代碼。不要在main或C++之後調用代碼。 – 2017-05-13 02:12:33

相關問題