在实际实现之前,我编写了一个小的原型代码,并将类构造函数和ctor构造函数放在同一个文件中,以查看ctor是否先执行,这是我的实际实现。
但是,我正面临一个错误。这是代码:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <iostream>
using namespace std;
extern "C" void startMe(void) __attribute__ ((constructor(1)));
extern "C" void ending(void) __attribute__ ((destructor));
class Test {
public:
Test()
{
cout << "This is test constructor" << endl;
}
};
int main()
{
Test();
printf("Now main called\n");
}
void startMe(void)
{
printf("Start me called before main\n");
}
void ending(void)
{
printf("Destructor called\n");
}
-
Output:
$ g++ constructor1.cc
constructor1.cc:10: error: wrong number of arguments specified for ‘constructor’ attribute
但是,当我删除构造函数优先级时,它编译并运行正常。也就是说,我这样做:
extern "C" void startMe(void) __attribute__ ((constructor));
为什么会这样?如何优先考虑?
请帮帮我。我的想法是首先执行“ctor”,然后执行另一个(Test)构造函数。同样的原因,我把ctor作为优先事项1。
答案 0 :(得分:1)
按原样编译程序:
warning: constructor priorities from 0 to 100 are reserved for the implementation
将优先级从1更改为101可以消除警告,并且可执行文件会生成:
Start me called before main
This is test constructor
Now main called
Destructor called
这是使用GCC 4.5
答案 1 :(得分:0)
为'constructor'属性指定的参数数量错误
看起来你正在使用GCC的低级版本。
根据GCC 4.2.1文档,以下是相关的GCC 4.2.1 Function Attributes:
构造
析构函数
构造函数 属性导致函数在之前自动调用 执行进入main ()
...
相关的GCC 4.3.0 Function Attributes:
构造
析构函数
构造函数(优先级)
析构函数(优先级)
构造函数 属性导致函数在之前自动调用 执行进入main ()
...
解决方案是使用GCC 4.3或更高版本。
我目前正在OpenBSD 5.7上测试一些软件,它附带了GCC 4.2.1编译器。我们还支持CentOS 5,并附带GCC 4.1编译器。以下是代码的外观:
// INIT_PRIORITY manages initialization of C++ static objects. Under GCC,
// the library uses init_priority attribute in the range [INIT_PRIORITY,
// INIT_PRIORITY+100]. Under Windows, INIT_PRIORITY enlists
// "#pragma init_seg(lib)". Undefine or set to 0 to disable it.
#define INIT_PRIORITY 250
#ifdef __GNUC__
# define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#endif
#ifdef __clang__
# define CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
#endif
...
#if __GNUC__ && INIT_PRIORITY && ((GCC_VERSION >= 40300) || (CLANG_VERSION >= 20900))
DLL void API DetectX86Features() __attribute__ ((constructor (INIT_PRIORITY + 50)));
DLL bool API CpuId(word32 input, word32 *output);
#elif __GNUC__ && INIT_PRIORITY
DLL void API DetectX86Features() __attribute__ ((constructor));
DLL bool API CpuId(word32 input, word32 *output);
#else
DLL void API DetectX86Features();
DLL bool API CpuId(word32 input, word32 *output);
#endif
您可能应该创建一个额外的类,例如Initialization
,并将startMe
放在构造函数中,将ending
放在析构函数中。然后,创建C ++对象的静态实例,如Initialization init;
。
要避免 static initialization order fiasco ,您应该使用init_priority
(另请参阅GCC邮件列表中的this Stack Overflow question和Clarification of attribute init_priority)。 init_priority
以来sbt-launch.jar
一直存在。