#pragma 预处理指令详解
程序员文章站
2022-05-04 23:34:19
...
#pragma 预处理指令详解
- #pragma 指令对每个编译器给出了一个方法,在保持C和C++语言完全兼容的情况下,给出了主机或操作系统专有的特征。
- 其格式一般是
#pragma para
,其中para 是参数。
message 参数
- 它能够在编译窗口中输出相应的信息,这对于源代码的控制是非常重要的。
- 使用方法
#pragma message("消息文本")
- 当编译器遇到这条指令时,就在编译输出窗口中将消息文本打印出来。
- 比如:我们在程序中定义了许多宏来控制源代码版本时,我们自己有时候可能会忘记有没有正确的设置这些宏,此时我们就可以这样做。
#ifdef _x64
#pragma message("_x64 macro activated!")
#endif
#pragma code_seg
#pragma code_seg( [ " section-name " [ , " section-class " ] ] )
- 它能够设置程序中函数代码存放的代码段,当我们在开发驱动程序的时候就会使用到它。
#pragma once
- 其作用是在头文件的最开始加入这条指令以保证头文件被编译一次。但 #pragma once 是编译器相关的,就是说在这个编译系统上能用,但是在其他系统上就不一定能用,所以其可移植性较差。一般如果强调程序跨平台,还是选择使用
#ifndef, #define, #endif
比较好。
#pragma hdrstop
- 表示预编译头文件到此为止,后面的文件不进行编译
#pragma resouce
- 比如
#pragma resouce "*.dfm "
表示把 *.dfm 文件中的资源添加到工程。
#pragma comment
- 该指令将一个注释记录放入一个对象文件或可执行文件中。
- 常用的lib 关键字,可以帮我们连入一个库文件。
- 比如:
#pragma comment(lib, "comct132.lib")
#pragma pack 与内存对齐问题
- 许多实际的计算机系统对基本类型的数据在内存中存放的位置有限制,他们会要求这些数据的首地址的值是某个数 K (通常是4或者8的倍数),这就是所谓的内存对齐。
- win32 下的对齐数是8,linux 下的对齐数是4。
- 比如
#pragma pack(1)
,就是我设置对齐数是1,有什么好处呢,我们来看一个例子。 - 比如:在网络协议编程中,经常会处理不同协议的数据报文。一种方法是通过指针偏移的方式来得到各种信息,但这样做不仅编程复杂,而且协议一旦有变化,程序改起来也比较麻烦。但是现在我们可以利用这一特性自己定义自己的协议结构,通过访问结构中的各种成员来获取各种信息。这样做,不但简化了编程,而且即使协议发生变化,我们也只需要修改协议结构的定义即可,其他程序无需修改。看看下面的TCP 协议首部,说明如何定义协议结构。
#pragma pack(1) //按照1字节方式进行对齐
struct TCPHEADER
{
shortSrcPort; //16位源端口号
shortDstPort; //16位目的端口号
intSerialNo; //32位***
intAckNo; //32位确认号
unsignedcharHaderLen:4; //4位首部长度
unsignedcharReserved1:4; //保留16位中的4位
unsignedcharReserved2:2; //保留16位中的2位
unsignedcharURG:1;
unsignedcharACK:1;
unsignedcharPSH:1;
unsignedcharRST:1;
unsignedcharSYN:1;
unsignedcharFIN:1;
shortWindowSize; //16位窗口大小
shortTcpChkSum; //16位TCP检验和
shortUrgentPointer; //16位紧急指针
};
#pragm apop() //取消1字节对齐方式
- #pragma pack规定的对齐长度,实际使用的规则是: 结构,联合,或者类的数据成员,第一个放在偏移为0的地方,以后每个数据成员的对齐,按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行。 但是,当#pragma pack的值等于或超过最长数据成员的长度的时候,这个值的大小将不产生任何效果。 而结构整体的对齐,则按照结构体中最大的数据成员进行。
下一篇: python函数 - bytearray