HOW TO: Use #pragma init_seg to control static construction

http://support.microsoft.com/kb/104248

在 Microsoft C++ 编译器,是可以控制您的静态对象,在文件范围内,声明是构造和销毁通过使用 #pragama init_seg 预处理器指令时。

有四个选项为 init_seg 预处理器指令: 编译器、 lib、 用户和"user_defined_segment_name"。 在源代码,此指令者必须在窗体:

     #pragma init_seg(compiler)
     #pragma init_seg(lib)
     #pragma init_seg(user)
     #pragma init_seg("user_defined_segment_name")
注意: 仅一个 init_seg 指令可以出现在单个源文件。 否则,编译器会产生"错误 C2356: 初始化段在翻译单元不能更改"

此指令旨在使开发人员能够组应用程序中的构造函数。 这将很有用如果某些对象依赖其他对象正常工作的存在。 分组在一起使用 # pragma init_seg(compiler) 的对象是所有其他对象之前构造并销毁后应用程序中的所有其他对象。 这用于在运行时库中的对象。 例如,因为 cin 和 cout 可能或可能不能使用您的构造函数或析构函数,它使用 init_seg(compiler) 中的这些对象构造还,# pragma 将是 unwise。

对象分组在一起使用 # pragma init_seg(lib) 的是构造后并销毁之前使用 # pragma init_seg(compiler),编译模块中的对象,但在应用程序中的所有其他对象之前。 分组在一起使用 # pragma init_seg(user) 的对象构造后且销毁前使用 # pragma init_seg(compiler) 和 # pragma init_seg(lib) 编译模块中的对象。 in other words,objects that are grouped together using #pragma init_seg(user) are constructed and destructed at as all that were not grouped using #pragma init_seg other static objects same time。

该文档不是完全清除此点上。 它表明用户组中的对象上一次构造。 这意味着这些对象是构造后并销毁编译器和 lib 组之前。 一种方法可以控制构造和破坏在每个组的顺序是若要更改的链接顺序。 出现在链接线中更早版本模块将被构造后并销毁的模块在同一个 init_seg 组中出现在链接线中更高版本之前。 构造函数是以相反的顺序调用它们段中的外观。

是务必注意 C++ 语言不保证的 nonderived 对象构造的任何顺序 ; C++ 语言保证这些对象会构造,和基类会构造从它们派生的类之前。

# pragma init_seg("user_defined_segment_name") 预处理器指令将构造函数的地址放入到逻辑段"user_defined_segment_name"。 此选项很有用只有您修改启动代码以调用这些构造函数。

下面的代码示例 (四个源文件) 演示上面的想法。 编译所有的源文件之后, 两种方式下所示,运行结果可执行文件链接它们。 从每个输出将显示它的 init_seg 选项而不依赖链接顺序。

使用 Visual C++ 32 位 Edition 版本,:
   link file1 file2 file3 file4 /out:demo1.exe
link file4 file3 file2 file1 /out:demo2.exe
With Visual C++ 16-位版本,使用:
   link file1 file2 file3 file4, demo1;
link file4 file3 file2 file1, demo2

示例代码

// file1.cpp
// command line: cl /c file1.cpp
#pragma init_seg(compiler)
#include<stdio.h>
class MyCompClass
{
public:
MyCompClass(){ printf("In the ctor of MyCompClass\n");}
~MyCompClass(){ printf("In the dtor of MyCompClass\n");}
} MyComp;
// file2.cpp
// command line: cl /c file2.cpp
#pragma init_seg(lib)
#include<iostream.h>
class MyLibClass
{
public:
MyLibClass(){cout<<"In the ctor of MyLibClass"<<endl;}
~MyLibClass(){cout<<"In the dtor of MyLibClass"<<endl;}
} MyLib;
// file3.cpp
// command line: cl /c file3.cpp
#pragma init_seg(user)
#include<iostream.h>
class MyUserClass
{
public:
MyUserClass(){cout<<"In the ctor of MyUserClass"<<endl;}
~MyUserClass(){cout<<"In the dtor of MyUserClass"<<endl;}
} MyUser;
// file4.cpp
// command line: cl /c file4.cpp
#include<iostream.h>
class MyRegularClass
{
public:
MyRegularClass(){cout<<"In the ctor of MyRegularClass"<<endl;}
~MyRegularClass(){cout<<"In the dtor of MyRegularClass"<<endl;}
} MyRegular;
void main(){}

posted on 2008-11-28 12:21  cgwolver  阅读(652)  评论(0)    收藏  举报

导航