#pragma 预编译指令的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的情况下,给出主机或操作系统专有的特征。

  其使用的格式一般为: #pragma Para。其中Para 为参数,常见的参数如下:

(1)Message参数

  Message参数编译信息输出窗口中输出相应地信息,使用方法如下:

  1. #pragma message("消息文本")

  使用示例,假如在程序中我们定义了很多宏来控制源代码版本的时候,我们自己有可能都会忘记有没有正确的设置这些宏,此时我们可以用这条指令在编译的时候就进行检查。假设我们希望判断自己有没有在源代码的什么地方定义了_X86这个宏可以用下面的方法:

  1. #ifdef _X86
  2. #pragma message("_X86 macro activated!")
  3. #endif

(2)code_seg参数

  code_seg参数可以设置程序中函数代码存放的代码段,使用方式如下:

  1. #pragma code_seg(["section-name"[,"section-class"]])

(3)#program once 参数

  其作用是在在头文件的最开始加入这条指令,以保证头文件被编译一次。但#program once是编译器相关的,就是说在这个编译系统上能用,但在其他的编译系统上就不一定能用,所以其可移植性较差。一般如果强调程序跨平台,还是选择使用“#ifndef,   #define,   #endif”比较好。

(4)#program hdrstop

  #program hdrstop表示预编译头文件到此为止,后面的头文件不进行编译。

(5)#program resource

  #program resource  “*.dfm”表示把*.dfm文件中的资源添加到工程。

(6)#program comment

  #program comment将一个注释记录放入一个对象文件或可执行文件。

(7)#program data_seg

  #program data_seg用来建立一个新的数据段并定义共享数据。如下:

  1. #pragma data_seg"shareddata")
  2. HWNDsharedwnd=NULL;//共享数据
  3. #pragma data_seg()

说明:a. #pragma data_seg()一般用于DLL中。也就是说,在DLL中定义一个共享的有名字的数据段。最关键的是:这个数据段中的全局变量可以被多个进程共享,否则多个进程之间无法共享DLL中的全局变量。

   b. 共享数据必须初始化,否则微软编译器会把没有初始化的数据放到.BSS段中,从而导致多个进程之间的共享行为失败。例如:

  1. #pragma data_seg("MyData")
  2. intg_Value;    //Note that the global is not initialized.
  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,这就实现了跨进程之间的数据通信。

(8)#program region

  #program region用于折叠特定的代码段,示例如下:

  1. #pragma region Variables
  2. HWND hWnd;
  3. const size_t Max_Length = ;
  4. //other variables
  5. #pragma endregion This region contains global variables.

应用实例:在网络协议编程中,经常会处理不同协议的数据报文。一种方法是通过指针偏移的方法来得到各种信息,但这样做不仅编程复杂,而且一旦协议有变化,程序修改起来也比较麻烦。在了解了编译器对结构空间的分配原则之后,我们完全可以利用这一特性定义自己的协议结构,通过访问结构的成员来获取各种信息。这样做,不仅简化了编程,而且即使协议发生变化,我们也只需修改协议结构的定义即可,其它程序无需修改,省时省力。下面以TCP协议首部为例,说明如何定义协议结构。

协议的定义结构如下:

  1. #pragma pack(1)  //按照1字节方式进行对齐
  2. struct TCPHEADER
  3. {
  4. shortSrcPort;  //16位源端口号
  5. shortDstPort;  //16位目的端口号
  6. intSerialNo;  //32位序列号
  7. intAckNo;    //32位确认号
  8. unsignedcharHaderLen:;  //4位首部长度
  9. unsignedcharReserved1:;  //保留16位中的4位
  10. unsignedcharReserved2:;  //保留16位中的2位
  11. unsignedcharURG:;
  12. unsignedcharACK:;
  13. unsignedcharPSH:;
  14. unsignedcharRST:;
  15. unsignedcharSYN:;
  16. unsignedcharFIN:;
  17. shortWindowSize;  //16位窗口大小
  18. shortTcpChkSum;  //16位TCP检验和
  19. shortUrgentPointer;  //16位紧急指针
  20. };
  21. #pragm apop()  //取消1字节对齐方式

#pragma pack规定的对齐长度,实际使用的规则是: 结构,联合,或者类的数据成员,第一个放在偏移为0的地方,以后每个数据成员的对齐,按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行。 但是,当#pragma pack的值等于或超过最长数据成员的长度的时候,这个值的大小将不产生任何效果。 而结构整体的对齐,则按照结构体中最大的数据成员进行。

本文学习内容参考:http://baike.baidu.com/link?url=Y2VbztMyL0ZfAA39g11DE3jPgGaaPhe9UXM4lKSsH6COB_90G8N2_W6bfA-tSBcE5ZYVGMYhqdghceMJ0_dyq_#1

http://blog.csdn.net/jx_kingwei/article/details/367312

C++ #pragma 预处理指令的更多相关文章

  1. #pragma 预处理指令详解

    源地址:http://blog.csdn.net/jx_kingwei/article/details/367312 #pragma  预处理指令详解              在所有的预处理指令中, ...

  2. pragma comment的使用 pragma预处理指令详解

    pragma comment的使用 pragma预处理指令详解   #pragma comment( comment-type [,"commentstring"] ) 该宏放置一 ...

  3. #pragma预处理指令讲解

    在所有的预处理指令中,#Pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作.#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的 ...

  4. C++中的#pragma 预处理指令详解

    源地址:http://blog.csdn.net/roger_77/article/details/660311 在所有的预处理指令中,#pragma 指令可能是最复杂的了,它的作用是设定编译器的状态 ...

  5. #pragma 预处理指令

    Linux C 编程一站式学习 #pragma 预处理指示供编译器实现一些非标准的特性,C 标准没有规定 #pragma 后面应该写什么以及起什么作用,由编译器自己规定.有的编译器用 #pragma ...

  6. C/C++预处理指令

    预处理指令 Preprocessor Directives define undef ifdef ifndef if endif else and elif line error include 预定 ...

  7. 预处理指令#pragma

    #pragma介绍 #pragma是一个预处理指令,pragma的中文意思是『编译指示』.它不是Objective-C中独有的东西(貌似在C/C++中使用比较多),最开始的设计初衷是为了保证代码在不同 ...

  8. 预处理指令中#Pragma

    在所有的预处理指令中,#Pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作.#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的 ...

  9. C/C++预处理指令#define,#ifdef,#ifndef,#endif…

    2016年12月29日更新: 今天查看以前文件的时候, 突然发现了#error 这个预处理指令.然后回想一下工作, 发现这个指令使用场景还是很多的.比如: 一个项目的模块儿之多,源文件之大,代码之多, ...

随机推荐

  1. C#- 实用的Log4Net日志记录例子

    工作中也是要用到日志记录的,LOG4NET在这块做的不错,以后可以继续拿来用. 1.引用DLL 2.LOG4NET的配置文件 <?xml version="1.0" enco ...

  2. 精彩,sinox.org官网贴满winxp死亡大字报

    sinox杀死windowxp不可避免,不用说,微软还自己掐死他!!! 中国人会升级正版 windows7吗?昨天也许会,但今天不会了,因为 sinox大字报出来了! 这下举国皆知了. 换装sinox ...

  3. mysql事物

    一. 什么是事务 事务就是一段sql 语句的批处理,但是这个批处理是一个atom(原子) ,不可分割,要么都执行,要么回滚(rollback)都不执行. 二.为什么出现这种技术 为什么要使用事务这个技 ...

  4. Unity3d 使用NPOI读写Excel 遇到的问题

    开发环境:unity5.3  NPOI(.net 2.0版  http://npoi.codeplex.com/) 运行环境:PC版, 其他平台没有测试 先上效果图: 实现步骤: 1.新建一个Exce ...

  5. hbase多用户入库,regionserver下线问题

    近期对hbase多用户插入数据时,regionserver会莫名奇妙的关闭,regionserver的日志有很多异常: 如下: org.apache.hadoop.hbase.DroppedSnaps ...

  6. Design Pattern Explained 读书笔记二——设计模式序言

    设计模式的由来: 20 世纪 90 年代初,一些聪明的开发者偶然接触到 Alexander(Christopher Alexander 的建筑师) 有关模式的工作.他们非常想知道,在建筑学成立的理论, ...

  7. Oracle 11g系统自己主动收集统计信息的一些知识

    在11g之前,当表的数据量改动超过总数据量的10%,就会晚上自己主动收集统计信息.怎样推断10%.之前的帖子有研究过:oracle自己主动统计信息的收集原理及实验.这个STALE_PERCENT=10 ...

  8. uboot官方FTP下载地址

    ftp://ftp.denx.de/pub/u-boot/

  9. C#_Ajax_分页

    using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace MvcTe ...

  10. Java基础知识强化之网络编程笔记20:Android网络通信之 Android常用OAuth登录和分享

    1.  申请百度开发者账号及百度OAuth简介. (1)申请开发者账号: http://developer.baidu.com/ (2)创建项目: http://developer.baidu.com ...