pragma 预处理指令
pragma 预编译指令
progma
指令是一条C/C++的预编译指令,旨在为配置编译选项,或者自定义编译过程。每个编译程序可以用#pragma
指令**或终止该编译程序支持的一些编译功能。
目录
文章目录
#pragma message
#pragma message("消息文本")
- 当编译器遇到这条指令时就在编译输出窗口中将消息文本打印出来,当我们在程序中定义了许多宏来控制源代码版本的时候,我们自己有可能都会忘记有没有正确的设置这些宏,此时我们可以用这条指令在编译的时候就进行检查。假设我们希望判断自己有没有在源代码的什么地方定义了
_X86
这个宏,可以用下面的方法:
#ifdef _X86
#pragma message("_X86 macro activated!")
#endif
- 我们定义了_X86这个宏以后,应用程序在编译时就会在编译输出窗口里显示"_86 macro activated!"。我们就不会因为不记得自己定义的一些特定的宏而抓耳挠腮了。
#pragma code_seg
#pragma code_seg( ["section-name" [, "section-class"] ] )
- 它能够设置程序中函数代码存放的代码段,当我们开发驱动程序的时候就会使用到它。
#pragma data_seg
- 用
#pragma data_seg
建立一个新的数据段并定义共享数据,其具体格式为:
#pragma data_seg("shareddata")
2 HWND sharedwnd = NULL;//共享数据
3 #pragma data_seg()
-
#pragma data_seg()
一般用于DLL
中。也就是说,在DLL
中定义一个共享的有名字的数据段。最关键的是:这个数据段中的全局变量可以被多个进程共享,否则多个进程之间无法共享DLL
中的全局变量。 - 共享数据必须初始化,否则微软编译器会把没有初始化的数据放到
.BSS
段中,从而导致多个进程之间的共享行为失败。例如,
#pragma data_seg("MyData")
2 int g_Value;//未初始化的变量
3 #pragma data_seg()
4 //DLL提供两个接口函数:
5 int GetValue()
6 {
7 return g_Value;
8 }
9 void SetValue(int n)
10 {
11 g_Value=n;
12 }
- 然后启动两个进程A和B,A和B都调用了这个
DLL
,假如A调用了SetValue(5)
; B接着调用int m = GetValue()
; 那么m
的值不一定是5,而是一个未定义的值。因为DLL
中的全局数据对于每一个调用它的进程而言,是私有的,不能共享的。假如你对g_Value
进行了初始化,那么g_Value
就一定会被放进MyData
段中。换句话说,如果A调用了SetValue(5)
; B接着调用int m = GetValue()
; 那么m
的值就一定是5,这就实现了跨进程之间的数据通信。
#pragma hdrstop
- 表示预编译头文件到此为止,后面的头文件不进行预编译。BCB可以预编译头文件以加快链接的速度,但如果所有头文件都进行预编译又可能占太多磁盘空间,所以使用这个选项排除一些头文件。
- 有时单元之间有依赖关系,比如单元A依赖单元B,所以单元B要先于单元A编译。
你可以用#pragma startup
指定编译优先级,如果使用了#pragma package(smart_init)
,BCB 就会根据优先级的大小先后编译。
#pragma resource
- 表示把*.dfm文件中的资源加入工程。*.dfm中包括窗体外观的定义。
#pragma warning
#pragma warning( disable: 4507 34; once: 4385; error: 164 )
- 等价于:
#pragma warning( disable: 4507 34 )
// 不显示4507和34号警告信息#pragma warning( once: 4385 )
// 4385号警告信息仅报告一次#pragma warning( error: 164 )
// 把164号警告信息作为一个错误。
#pragma comment
- 该指令将一个注释记录放入一个对象文件或可执行文件中。
- 常用的
lib
关键字,可以帮我们连入一个库文件。如:
#pragma comment(lib, "comctl32.lib")
- 和在工程设置里写上链入
comctl32.lib
的效果一样,不过这种方法写的 程序别人在使用你的代码的时候就不用再设置工程 settings 了。 - 其他指令
1、compiler:
放置编译器的版本或者名字到一个对象文件,该选项是被linker忽略的。
2、exestr:
在以后的版本将被取消。
#pragma loop_opt
- 开启或关闭对循环优化功能
#pragma loop_opt(on) // **
#pragma loop_opt(off) // 终止
#pragma pack
-
内存对齐问题
-
许多实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数k(通常它为4或8)的倍数,这就是所谓的内存对齐,而这个k则被称为该数据类型的对齐模数(alignment modulus)。
-
Win32平台下的微软C编译器(cl.exe for 80x86)在默认情况下采用如下的对齐规则: 任何基本数据类型T的对齐模数就是T的大小,即sizeof(T)。比如对于double类型(8字节),
就要求该类型数据的地址总是8的倍数,而char类型数据(1字节)则可以从任何一个地址开始。Linux下的GCC奉行的是另外一套规则(在资料中查得,并未验证,如错误请指正): 任何2字节大小(包括单字节吗?)的数据类型(比如short)的对齐模数是2,而其它所有超过2字节的数据类型(比如long,double)都以4为对齐模数。
ANSI C规定一种结构类型的大小是它所有字段的大小以及字段之间或字段尾部的填充区大小之和。填充区就是为了使结构体字段满足内存对齐要求而额外分配给结构体的空间。那么结构体本身有什么对齐要求吗?有的,ANSI C标准规定结构体类型的对齐要求不能比它所有字段中要求最严格的那个宽松,可以更严格。
#pragma once
- 只要在头文件的最开始加入这条指令就能够保证头文件被编译一次,这条指令实际上在VC6中就已经有了,
但是考虑到兼容性并没有太多的使用它。
#pragma hdrstop
- 表示预编译头文件到此为止,后面的头文件不进行预编译。BCB可以预编译头文件以加快链接的速度,
但如果所有头文件都进行预编译又可能占太多磁盘空间,所以使用这个选项排除一些头文件。
#pragma disable
- 在函数前声明,只对一个函数有效。该函数调用过程中将不可被中断。一般在
C51
中使用较多。
#pragma region
-
#pragma region
是Visual C++
中特有的预处理指令。它可以让你折叠特定的代码块,从而使界面更加清洁,便于编辑其他代码。折叠后的代码块不会影响编译。你也可以随时展开代码块以进行编辑等操作。如下格式
#pragma region name
#pragma endregion comment
举个例子
#pragma region Variables
3 HWND hWnd;
5 const size_t Max_Length = 20;
7 //other variables
9 #pragma endregion This region contains global variables.
参考博客:
https://blog.csdn.net/qq_35624156/article/details/79864947
https://www.cnblogs.com/fnlingnzb-learner/p/5854494.html