1、#pragma用法大全C和C+的每个实现对它的主机或操作系统都支持一些独有的特征。例如, 某些程序须对存放数据的存储器区域进行精确的控制,或必须控制特定函数接受参量的方式。#pragma指令对每个编译器给出了一个方法,在保持与C和 C+语言完全兼容的情况下,给出主机或操作系统专有的特征。依据定义,编译指示是机器或操作系统专有的,且对于每个编译器都是不同的。 语法 #pragma 语言符号字符串 语 言符号字符串是给出特有编译器指令和参量的字符序列。数字符号(#)必须是包含编译指示行中的第一个非空白字符。空白字符可分开数字符号(#)和单词 pragma 。在#pragma之后,可以编写翻译器作为
2、预处理器语言符号分析的任何文本。#pragma的参量从属于宏扩展。 如果编译器找到一个不能识别的编译指示,将发出一个警告,但编译将继续。编译指示可用在条件说明中,以提供新的预处理器功能,或提供定义的实现信息给编译器。C和C+编译器可识别下面的编译指示: alloc_text comment init_seg* optimize auto_inline component inline_depth pack bss_seg data_seg inline_recursion pointers_to_members* check_stack function intrinsic setlocale
3、 code_seg hdrstop message vtordisp* const_seg include_alias once warning* 仅被C+编译器支持 - C+编译器专有编译指示 以下是C+编译器专有的编译指示指令: * init_segl pointers_to_members * vtordisp init_seg C+特殊处 #pragma init-seg(complier/lib/user/ section-name ,func-name)该指令指定一个影响启动代码执行顺序的关键字或代码段。由于全局静态对象的初始化可能涉及执行代码,因此必须指定创建对 象时定义的一个关
4、键字。在动态连接库(DLL)或需初始化的库中使用init_seg编译指示尤其重要。 init_seg编译指示的选项如下: complier 该选项保留给Microsoft C运行库初始化。这个组中的对象最先被创建。lib 用于第三方类库供应商的初始化。该组中的对象在complier标志之后,其他标记之前创建。 user 用于任何用户。此组对象最后创建。 section_name 允许初始化段的显示规格。在一个用户指定section-name(段名称)中的对象不能被隐含地创建,但它们的地址可放在以section_name命名的段中。 func_name 指定在程序退出时在exit()地方调用的函
5、数。指定的函数必须与exit函数具有相同的特征:int funcname(void(_cdecl*)(void); 如果你需要延迟初始化过程(例如,在一个DLL中),你可以选择显式地指定该段名称。然后必须为每个静态对象调用构造函数。 C+特殊处结束 pointers_to_members C+特殊处 #progma pointers_to_members(指针说明,最一般表示) 该指令指定一个类成员的指针能否在其相关定义之前被说明,且用于控制该指针尺寸和解释该指针需要的代码。你可以把一个pointers_to_members编译指示放入你的源文件中替换/vmx编译器选项。 指针说明参量指定你在
6、一个关联函数定义之前还是之后说明了一个成员的指针。指针说明参量是以下两个符号之一: 参量 说明 full_generality 生成安全、但常常并非最优的代码。如果在关联类定义之前说明任何成员的指针,可使用full_generality。该参量通常使用最一般表示参量指定的指针表示形式。等同于/vmg选项 best_case 为所有成员指针使用最佳情况(best_case)表示生成安全的最优代码。使用该参量是需在定义一个类的成员指针说明之前定义此类。其缺省值为best_case best_case 为所有成员指针使用最佳情况(best_case)表示生成安全的最优代码。使用该参量是需在定义一个类
7、的成员指针说明之前定义此类。其缺省值为best_case 最一般表示参量说明了在转换单元中,编译器能够安全地引用任何指向类成员的指针的最小指针表示。该参量取如下值之一: 参量 说明 single_inheritance 最一般表示是单继承的,即一个成员函数的指针。对于其中说明了一个指向成员指针的一个类定义,若其继承模式说明为多重的或虚拟的,将导致错误 multiple_inheritance 最一般表示是多重继承的,即一个成员函数的指针。对于其中说明了一个指向成员指针的一个类定义,若其继承模式是虚拟的,将导致错误 vitual_inheritance 最一般表示是虚拟继承,即一个成员函数的指针
8、。该函数不会导致错误。当使用#pragma pointers_to_members(full_generality) 时这是个缺省参量 C+特殊处结束 vtordisp C+特殊处 #pragma vtordisp(on|off) 该 指令允许增加隐含的vtordisp构造函数/析构函数替换成员。vtordisp编译指示只使用虚基类的代码。若一个派生类重迭一个从虚拟基类继承的虚 拟函数,且如果派生类的一个构造函数或析构函数调用那个使用该虚拟基类指针的函数,则编译器可能将增加的隐含“vtordisp”域到有虚拟基的类中。 vtordisp 编译指示会影响其后类的分布。/Vd0或/Vd1选项指定了
9、对于完全模式的相同动作。指定off将抑制隐含的vtordisp成员。指定缺省值on, 将在需要的位置打开它们。Vtordisp指令仅在类的构造/析构函数在用this 指针指向的对象处不可能调用虚拟函数时关闭。 #pragma vtordisp(off) class GetReal:virtual public.; #pragma vtordisp(on) C+特殊处结束 - C和C+编译器编译指示 以下是为C和C+编译器定义的编译指示: alloc_text component init_seg* optimize auto_inline const_seg inline_depth pack
10、 bss_seg data_seg inline_recursi onpointers_to_members* check_stack function intrinsic setlocale code_seg hdrstop message vtordisp* comment include_alias once warning * 仅被C+编译器支持 alloc_text#pragma alloc_text(“文本段”,函数1,.) 该指令用于命名指定的函数定义将要驻留的代码段。该编译指示对已命名的函数必须出现在一个函数说明符和该函数定义之间。 alloct_text编译指示并不处理C+成
11、员函数或重载函数。它仅用于以C连接方式说明的函数,这指的是用extern“C”连接规格说明的函数。如果你试图将此编译指示用于非C+连接的函数,将产生一个编译错误。 由于不支持使用_based的函数地址,指定段位址需要使用alloc_text编译指示,以文本段指定的名称应包括在双引号间。 alloc_text 编译指示必须出现在指定的函数说明之后,这些函数的定义之前。一个alloc_text编译指示中的函数引用必须在此编译指示的同一模块中定义。如果未这 样做,且一个未定义的函数随后被编译到一个不同的文本段,则这个错误可能找得到,也可能找不到。虽然该程序一般会正常运行,但该函数不会分配到预期的段
12、中。 alloc_text的其他限制如下: * 它不能用在一个函数的内部。 * 它必须在已说明的函数之后和已定义的函数之前使用。 auto_inline #pragma auto_inline(on|off) 排 除自动内联扩展的候选者中指定为off的区域中定义的函数。为了使用auto_inline编译指示,把它放在一个函数定义之前或立即之后(不在该函数定 义之内)。在看到该编译指示之后的第一个函数定义处,该编译指示发生作用。编译指示auto_inline不能应用于显式内联函数。 bss_ seg#pragma data-seg(section-name,section-class) 指定未初
13、始化数据的缺省段。data_seg编译指示处理初始化或未初始化数据有相同的作用。在某些情况下,你可以使用bss_seg通过把所有未初始化数据放在一个段中来加速加载的时间。 #pragma bss_seg(MY_DATA) 导致#pragma语句后未初始化的数据分配到一个名称为MY_DATA的段中。 用bss_seg编译指示分配的数据不会保留关于它的位置的任何信息。 第二个参量section_class用于与Visual C+之前的版本兼容,现在已被忽略。 check_stack #pragma check_stack(on|off) #pragma check_stack+|- 该指令在off
14、(或-)选项时指示编译器关闭栈搜索。在on(或+)选项指定时,打开搜索。 若无参量,栈搜索就按缺省情况处理。在看到该编译指示之后第一个定义的函数处发生作用。栈搜索既不是宏的一部分,也不是产生的内联函数的一部分。 如果未赋予一个参量给check_stack编译指示,栈检查将还原成在命令行中说明的行为,有关更多的信息参见“编译器参考”。#pragma check_stack和/Gs选项的交互关系参见表2.1。 表2.1 使用check_stack编译指示 语法 是否用/Gs选项编译 行为 #pragma check_stack()或#pragma check_stack 是 关闭其后函数的栈检查
15、#pragma check_stack()或#pragma check_stack 否 打开其后函数的栈检查 #pragma check_stack(on)或#pragma check_stack + 是或否 打开其后函数的栈检查 #pragma check_stack(off)或#pragma check_stack - 是或否 关闭其后函数的栈检查 code_seg #pragma code_seg(section-name,section-class) 该指令用于指定一个分配函数的代码段。code_seg编译指示指定了函数的缺省段。 你可以有选择性地指定类和段名。使用没有section-
16、name字符串的#pragmacode_seg可在编译开始时将其复位。 const_seg #pragma const_seg(section-name,section-class) 该指令用于指定对于常量数据的缺省段。data_seg编译指示对所有数据具有相同作用。你可以用此指令将你的所有常量数据放入一个只读段中。 #pragma const_seg(MY_DATA) 导致该指令将#pragma语句后的常量数据放入一个名称为MY_DATA的段里。 使用const_seg编译指示分配的数据不会保留有关它的位置的任何信息。 第二个参数section-class用于与Visual C+ 2.0版之
17、前的版本兼容,现在已可忽略。 comment #pragma comment(comment-type,commentstring) 该 指令将一个注释记录放入一个对象文件或可执行文件中。comment-type是下面五种说明的预定义标识符之一,它们指出了注释记录的类型。任选的 commentstring是给一些注释类型提供额外信息的字符串文字。由于commentstring是一个字符串文字, 因此它必须遵循对于字符串文字的诸如转义字符、嵌lib 该选项将一个库搜索记录放入对象文件。该注释类型必须带有一个 commentstring参数。这个参数包含你想要的链接器搜索的库的名称(有可能包含路径
18、)。由于在对象文件中该库名称在缺省的库搜索记录之前,所以 链接器搜索该库就象你在命令行中命名了它一样。你可以把多个库搜索记录放在同一个源文件中,每个记录在对象文件中都以其在源文件中出现的同样顺序出现。 linker 该选项将一个链接器选项放入对象文件中。可以用该注释类型指定一个链接器选项,用于取代在Project Setting对话框中Link选项卡上放入该选项。例如,你可以指定/include选项来强行包括一个符号: #pragma comment(linker,/include:_symbol) user 该选项将一个一般的注释放入对象文件中。commentstring参量包含了该注释的文
19、本。这个注释记录被链接器忽略。 以下编译指示导致链接器在连接时搜索EMAPI.LIB库。 该连接器首先在当前工作目录中搜索,随后在LIB环境变量说明的路径中搜索。 #pragma comment(lib,emapi) 以下编译指示导致编译器把编译器的名称和版本号放入对象文件: #pragma comment(complier) 注意:对于一个带commentstring参量的注释, 你可以在任何要使用一个字符串文字的地方使用宏,让这个宏扩展为一个字符串文字。你也可以把任何一个字符串文字的任何组合与扩展为字符串文字的宏合并起来,例如:下面的语句是可以接受的: #pragma comment(us
20、er,Compiled on _DATA_ _ at _ _TIME_ _) component#pragma component(browser,on|off,references,name)#pragma component(minrebuild,on|off) 该指令用于控制源文件内的浏览信息或依赖信息的集合。 browser 你可以打开或关闭集合,并可以在收集信息时指定忽略的特定名称。 用on或off选项控制前面编译指示的浏览信息的集合。例如: #pragma component(browser,off) 该指令让编译器停止收集浏览信息。 注意:用此指令打开浏览信息的集合,浏览信息必须
21、先用Project Settings对话框或命令行打开。 references选项可带也可不带name参量。不带name参量的references选项用于打开或关闭引用的集合(但此时继续收集其它浏览信息)。例如: #pragma component(browser,off,references) 该指令使编译器停止收集引用信息。 带name和off参量的references选项,用于防止浏览信息窗口中出现对name的引用。使用这种语法可忽略你不感兴趣的名称和类型, 并且可缩短浏览信息的尺寸。例如: #pragma component(browser,off,references,DWORD)
22、忽略该点之前对于DWORD的引用。但你可用on选项把对于DWORD引用的集合重新打开。 #pragma component(browser,on,references,DWORD) 这是恢复对name引用集合唯一的方式;用此方式你可以显式地打开任何你已经关闭的name。 为了防止预处理器把name展开(如把NULL扩展为0),将它加上引号: #pragma component(browser,off,references,NULL) Minimal Rebuild Visual C+的minimal rebuild(最小重建)特性需要编译器创建和存储依赖信息的C+类,这将占用磁盘空间。为了节省
23、磁盘空间,你可以在任何你不需收集依赖信息的时候仅 用#pragma component(minirebuild,off),例如,在不变的头文件中。在不变的类后插入#pragma component(minrebuild,on)可重新打开依赖信息。 有关更多的信息参见Enable Minimal Rebuild(/Gm)编译器选项。 data_seg #pragma data_seg(section-name,section-class) 该指令指定数据的缺省段。例如: #pragma data_seg(MY_DATA) 将#pragma语句后分配的数据放在以名称为MY_DATA的段里。 使用d
24、ata_seg编译指示分配的数据不会保留关于它的位置的任何信息。 第二个参量section-class用于与Visual C+ 2.0之前的版本兼容,现在已可忽略。 function #pragma function(function1,function2,.) 该 指令指定对在生成的编译器编译指示参量表中指定调用的函数。如果你使用intrinsic编译指示(或/Oi)告诉编译器生成内在函数(被生成为内联代 码,而非函数调用的内在函数),就能用function编译指示来显式地强制调用一个函数。当一个函数编译指示出现时,它在第一个包含一个指定的内在函数 的函数定义处发生作用,这个作用持续到源文件
25、的结尾或直到一个说明这种相同的内在函数的编译指示出现为止。在全局层时,该function编译指示只能用 在一个函数外。对于具有内部形式的函数表,参见#pragma intrinsic。 hdrstop #pragma hdrstop(filename) 该 指令用于控制预编译头文件的工作方式。filename是预编译头文件使用或创建的名称(根据指定选项/Yu或/Yc决定)。如果filename不包含 路径说明,预编译头文件将被假定在与源文件相同的目录中。当指定/YX自动预编译头文件选项时,所有filename都被忽略。 当采用/YX或/Yc编译时,一个C或C+文件包含一个hdrstop编译指示
26、,该编译器将把编译状态存入到编译指示的位置。该编译指示之后任何代码的编译状态都不存储。 hdrstop编译指示不可能出现在一个头文件中。它必须出现在源文件中。这指的是,它不能出现在任何数据、函数说明或函数定义中。 注意:除非/YX选项或无文件名的/Yu或/Yc选项被指定,否则hdrstop编译指示将被忽略。 该指令使用filename命名编译状态存储的预编译头文件。hdrstop和filename之间的一个空白是任选的。在hdrstop编译指示中说明的文件名称是一个字符串, 而且必须服从C或C+字符串的约束。尤其重要的是必须将其置于括号中 如下例所示: #pragma hdrstop(c:pr
27、ojectsincludemyinc.pch) 预编译头文件的名称由下列规则决定,顺序如下: 1. /Fp编译器选项的参量。 2. #pragma hdrstop的filename参量。 3. 以.PCH为扩展名的源文件的基名称。 include_alias #pragma include_alias(long_filename,short_filename) #pragma include_alias(,) 该 指令指定short_filename作为long_filename的别名。某些文件系统允许比8.3 FAT文件系统限定更长的文件名。编译器不能够简单地把更长的头文件名截短为8.3格式
28、,因为这种更长的头文件名的开始八个字符可能不是唯一的。只要编译 器遇到long_filename字符串,就用short_filename替换,并且代替查找short_filename头文件。这个编译指示必须出 现在相应的#include指令之前, 例如:/ /这两个文件的开头八个字符不是唯一的 #pragma include_alias(AppleSystemHeaderQuickdraw.h,quickdra.h) #pragma include_alias(AppleSystemHeaderFruit.h,fruit.h) #pragma include_alias( GraphicsMe
29、nu.h, gramenu.h) #include AppleSystemHeaderQuickdraw.h #include AppleSystemHeaderFruit.h #include GraphicsMenu.h 无论是拼写,还是双引号或尖括号的用法,被搜索的别名都必须符合规格。include_alias编译指示在该文件名中处理简单的字符串匹配,而在其它的文件名中是无效的。例如,给出如下指令: #pragma include_alias(mymath.h,math.h) #include ./mymath.h #include sys/mymath.h 没有别名使用(替换)被执行,
30、因为头文件字符串并不匹配。用作/Yu、/Yc和/YX编译器选项参量的头文件名,或hdrstop编译指示的头文件名也不能被替换。例如,若你的源文件包含下列指令: #include 相应的编译器选项应该是: /YcAppleSystemHeaderStop.h 你可以用include_alias编译指示把任何头文件名映射为另一个。例如: #pragma include_alias(api.h, c:version1.0api.h) #pragma include_alias(, ) #include api.h #include 不要把双引号内的文件名和尖括号内的文件名相混淆,例如,对于上面给出的两个#pragma include_alias指令,编译器在下面的#include指令中不执行任何替换: #include Include stdio.h 此外,下面的指令将导致错误: #pragma include_alias(,header.h) /错误 注意在错误信息中给出的文件名,或作为预先定义的_FILE_宏的值,是替换执行之后的文件的名称,例如,下面指令后: #pragma include_alias(VeryLongFileName.H,myfile.h ) #include VeryLongFileName
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1