2010-03-17 65 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