c++ #Pragma

2023-01-30  本文已影响0人  AArman
//定义了_X86 宏以后,应用程序在编译时就会在编译输出窗口里显示message
#ifdef _X86
   #Pragma message(“_X86 macro activated!”);  // 当编译器遇到这条指令时就在编译输出窗口中将消息文本打印出来
#endif


#pragma code_seg( ["section-name"[,"section-class"] ] ); //它可以设置程序中函数代码存放的代码段

#pragma once;     //只要在头文件的最开始加入这条指令就可以保证头文件被编译一次

#pragma hdrstop;  //表示预编译头文件到此为止,后面的头文件不进行预编译。BCB 能够预编译头文件以加快连接的速度,但若是全部头文件都进行预编译又可能占太多磁盘空间,因此使用这个选项排除一些头文件。


#pragma comment(lib, "user32.lib"); //将user32.lib 库文件加入到本工程



#pragma warning(disable:4507 34);    // 不显示4507 和34 号警告信息
#pragma warning(once:4385);         // 4385 号警告信息仅报告一次
#pragma warning(error:164);         // 把164 号警告信息做为一个错误

#pragma warning(push);        //保存全部警告信息的现有的警告状态
#pragma warning(push, n);      //保存全部警告信息的现有的警告状态,而且把全局警告等级设定为n
#pragma warning(pop);         //向栈中弹出最后一个警告信息,在入栈和出栈之间所做的一切改动取消

#pragma once 和 #ifndef _x_h 区别

  1. ifndef _x_h

    1. ifndef 的方式受C/C++语言标准支持。它不仅可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件(或者代码片段)不会被不小心同时包含

    2. ifndef受C/C++语言标准的支持,不受编译器的任何限制;

    3. 缺点:如果宏名称一样时,编译器会提示找不到声明
  2. pragma once

    1. 由编译器提供支持,同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。
    2. 不必担心宏名冲突问题
    3. 缺点:如果某个头文件有多份拷贝,本方法不能保证他们不被重复包含

pragma pack

  1. 机器的位数
    1. 计算机一次能处理数据的最大位数称为该机器的位数,位数跟电脑的CPU有关。
      1. 64位的机器一次最多从内存中读取8字节
      2. 32位的机器一次最多从内存中读取4字节
  2. 对齐系数
    1. 每个特定平台上的编译器都有自己的默认“对齐系数”
    2. 默认的结构体对齐系数,取决于成员中最大的变量所占的字节数,按照最大变量所占的字节数进行对齐,(sizeof(struct))

Q : 默认的对齐方式,可能造成CPU读取变量效率低,或者内存浪费。因为64位机器一次最多读取8位, 在c++中可以通过预编译命令,来调整对齐系数数。进而调整结构体的存储方式

  1. pragma pack(n)

    1. n=1,2,4,8,16来改变这一系数,其中的n就是要指定的“对齐系数”
  2. 对齐规则:
    1. 数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员的对齐按照#pragma pack 指定的数值和这个数据成员自身长度中,比较小的那个进行
    2. 结构(或联合)的整体对齐规则:在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行
    3. 如果 n 大于等于该变量所占用的字 节数,那么偏移量必须满足默认的对齐方式
    4. 如果 n 小于该变量的类型所占用 的字节数,那么偏移量为 n 的倍数,不用满足默认的对齐方式
    5. 结构的约束条件:
      1. 如果 n 大于所有成员变量类型所占用的字节数,那么结 构的总大小必须为占用空间最大的变量占用的空间数的倍数; 否则必须为 n 的倍数
      2. 如果 #pramga pack(n) 中的n大于结构体成员中任何一个成员所占用的字节数,则该n值无效。编译器会选取结构体中最大数据成员的字节数为基准
#pragma pack(n); //作用:C编译器将按照n个字节对齐
#pragma pack()  //作用:取消自定义字节对齐方式

#pragma pack(push, n); //作用:是指把原来对齐方式设置压栈,并设新的对齐方式设置为n个字节对齐
#pragma pack(pop);     //作用:恢复对齐状态
#pragma pack(1) // 按照1字节方式进行对齐
struct TCPHEADER 
{
     short SrcPort; // 16位源端口号
     short DstPort; // 16位目的端口号
     int SerialNo; // 32位序列号
     int AckNo; // 32位确认号
     unsigned char HaderLen : 4; // 4位首部长度
     unsigned char Reserved1 : 4; // 保留6位中的4位
     unsigned char Reserved2 : 2; // 保留6位中的2位
     unsigned char URG : 1;
     unsigned char ACK : 1;
     unsigned char PSH : 1;
     unsigned char RST : 1;
     unsigned char SYN : 1;
     unsigned char FIN : 1;
     short WindowSize; // 16位窗口大小
     short TcpChkSum; // 16位TCP检验和
     short UrgentPointer; // 16位紧急指针
}; 
#pragma pack()

上一篇下一篇

猜你喜欢

热点阅读