2010-03-17 42 views
10

我想構建一些調用共享庫的loadup代碼的代碼。我以爲我會做這樣的:#pragma init和#pragma fini在linux上使用gcc編譯器

#pragma init(my_init) 

static void my_init() { 
    //do-something 
} 

int add (int a,int b) { 
    return a+b; 
} 

所以當我建立一個代碼

的gcc -fPIC -g -c -Wall tt.c

它返回

gcc -fPIC -g -c -Wall tt.c 
tt.c:2: warning: ignoring #pragma init 
tt.c:4: warning: ‘my_init’ defined but not used 

所以它忽略了我的#pragmas。我在真實代碼中嘗試了這一點,並且我的代碼因爲函數沒有在編譯指示段中被調用而被中止,因爲它被忽略。

如何讓gcc使用這些#pragma init和fini語句?

回答

16

編譯指示幾乎都是編譯器特有的。 GCC沒有實現init,但你可以使用constructor功能屬性得到相同的效果:

static __attribute__((constructor)) void my_init() 
{ 
    //do-something 
} 

也有一個相應的destructor屬性。

+0

正是我一直在尋找! – Josh 2010-03-19 20:13:47

+0

嗯,對於gcc 4.4.6我在上面的例子中得到'''token'錯誤之前的'expected','或';'。當我從函數定義中移除該屬性,並在其之前放置一個帶有構造函數屬性的函數聲明時,它就像預期的一樣工作[記錄](http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html)。 – maxschlepzig 2013-05-12 12:58:02

+0

@maxschlepzig:該屬性需要在函數定義中的聲明器之前更新。 – caf 2013-05-12 13:52:19

-2

相反,使用C++:

 
// init.cpp 
namespace // an anonymous namespace 
{ 
    class autoinit 
    { 
     public: 
      ~autoinit(){ /* destruction code, if applicable */ } 
     private: 
      autoinit(){ /* content of myinit */ } 
      static autoinit _instance; 
    }; 

    autoinit 
    autoinit::_instance; // static instance forces static construction 
} 
+0

他可能需要在調用任何靜態構造函數之前調用其代碼,在這種情況下,這可能不起作用(初始化順序不能被控制並且不能保證),並且在標準C++中實際上幾乎是不可能的。 – 2010-03-17 05:07:26

+0

@Grant,你能控制用__attribute __((構造函數))聲明的函數的相對順序嗎?如果不是,它有什麼不同?此外,這種方法可以在所有C++實現中移植,而__attribute __((構造函數))語法僅適用於GCC。 – 2010-03-17 23:20:36

+1

我相信__attribute __((構造函數))語法確保它在所有其他代碼之前被調用。此外,它允許你指定該構造函數的優先級,所以如果指定了多個,它就知道按照什麼順序運行它們。至於可移植性,我說過在任何靜態類構造函數(即控制初始化)之前調用你的代碼isn不可能通過標準的C++,沒有可移植的方式。你只是簡單地指出我的意思,你的方法仍然不允許代碼在任何靜態類之前運行。 – 2010-03-17 23:48:38