在所有的预处理指令中,#pragma指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。#pragma指令对每个 编译器给出了一个方法,在保持与C和C++语言完全兼容的情况下,给出主机或操作系统专有的特征。依据定义,编译指示是机器或操作系统专有的,且对于每个 编译器都是不同的。其格式一般为:#pragma para,其中para为参数,下面来看一些常用的参数。

(Each   implementation   of   C   and   C++   supports   some   features   unique   to   its   host   machine   or   operating   system.   Some   programs,   for   instance,   need   to   exercise   precise   control   over   the   memory   areas   where   data   is   placed   or   to   control   the   way   certain   functions   receive   parameters.   The   #pragma   directives   offer   a  way   for   each   compiler   to   offer   machine-   and   operating-system-specific   features   while   retaining   overall   compatibility   with   the   C   and   C++   languages.   Pragmas   are   machine-   or   operating-system-specific   by   definition,   and   are   usually   different   for   every   compiler. )

(1)message参数。Message参数是我最喜欢的一个参数,它能够在编译信息输出窗口中输出相应的信息,这对于源代码信息的控制是非常重要的。其使用方法为:

#pragma message(“消息文本”),当编译器遇到这条指令时就在编译输出窗口中将消

息文本打印出来。

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

#ifdef   _X86

#pragma   message(“_X86   macro   activated!”)

#endif

当我们定义了_X86这个宏以后,应用程序在编译时就会在编译输出窗口里显示

“_X86   macro activated!”。我们就不会因为不记得自己定义的一些特定的宏而抓耳

挠腮了。

(2)另一个使用得比较多的pragma参数是code_seg。格式如:

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

它能够设置程序中函数代码存放的代码段,当我们开发驱动程序的时候就会使用到它。

(3)#pragma once (比较常用)。只要在头文件的最开始加入这条指令就能够保证

头文件被编译一次,这条指令实际上在VC6中就已经有了,但是考虑到兼容性并没有太多的使用它。

(4)#pragma hdrstop表示预编译头文件到此为止,后面的头文件不进行预编译。BCB

可以预编译头文件以加快链接的速度,但如果所有头文件都进行预编译又可能占太多磁盘空间,所以使用这个选项排除一些头文件。有时单元之间有依赖关系,比如单元A依赖单元B,所以单元B要先于单元A编译。你可以用#pragma   startup指定编

译优先级,如果使用了#pragma package(smart_init),BCB就会根据优先级的大小先

后编译。

(5)#pragma   resource   "*.dfm"表示把*.dfm文件中的资源加入工程。*.dfm中包括窗

体外观的定义。

(6)#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   warning   也支持如下格式:

#pragma   warning(   push   [   ,n   ]   )

#pragma   warning(   pop   )

这里n代表一个警告等级(1---4)。

#pragma   warning(   push   )保存所有警告信息的现有的警告状态。

#pragma   warning(   push,   n)保存所有警告信息的现有的警告状态,并且全局警告

等级设定为n。

#pragma   warning(   pop   )向栈中弹出最后一个警告信息,在入栈和出栈之间所作

的一切改动取消。例如:

#pragma   warning(   push   )

#pragma   warning(   disable   :   4705   )

#pragma   warning(   disable   :   4706   )

#pragma   warning(   disable   :   4707   )

//.......

#pragma   warning(   pop   )

在这段代码的最后,重新保存所有的警告信息(包括4705,4706和4707)。

(7)#pragma   comment(...) 该指令将一个注释记录放入一个对象文件或可执行

文件中。常用的lib关键字,可以帮我们连入一个库文件。

(8)#pragma   pack() 我们知道在VC中,对于想结构体Struct这样的类型,VC采

用8字节对齐的方式,如果我们不想使用8字节对齐(在网络变成中经常需要这样),我们可以在结构体前面加上

#pragma   pack(1)

struct

{

......

}

#pragma   pack()

二.#if _MSC_VER > 1000    #pragma once    #endif

(1)_MSC_VER。 Defines   the   compiler   version.   Defined   as   1200   for   Microsoft   Visual   C++   6.0.   Always   defined.

(2)#if   _MSC_VER   > 1000的意思是指如果vc编译器的版本大于1000则这个语句

被编译!大概小于1000的版本不支持#pragma   once这个语句。

(3)#pragma   once 。Specifies   that   the   file,   in   which   the   pragma   resides,

will   be   included   (opened)   only   once   by   the   compiler   in   a   build.   A   common   use   for   this   pragma   is   the   following:

//header.h

#pragma   once

//   Your   C   or   C++   code   would   follow:

#pragma   once    加入头文件的第一行 指示这个文件在编译时只被编译器文件编译

(打开)一次!一般用到.h中防止文件被重复包括!

三.#pragma once    与   #ifndef    #define   #endif

(1)从定义上即可看出,pragmas指令是某种机器或者操作系统独有的,并且不同编译器也常常有别。#pragma once这个是编译器相关指令,就是说在这个编译系统

上能用,但是在其他编译系统 不一定型,也就是说移植型差。不过现在基本上

已经是每个编译器都有这个定义了。

#ifndef   #define #endif这个是语言支持指令,这是C/C++语言中的宏定义,通过

宏定义避免文件多次编译。所以在所有支持C++语言的编译器上都是有效的。如果写的程序要   跨平台,最好使用这种方式。

(2)#ifndef   #define #endif   #ifndef 还有其它作用,防止头文件重复引用只是

其中一个应用而已。#pragma只有微软支持。

(3)#ifndef   #define #endif   他读到#ifndef之后,如果已经定义过了,就会跳过

这一大片,一直到#endif为止。这将增加build时间,因为每次compiler都会打开这个文件,然后搜索全文件一遍。而如果碰到了#pragma once,他就会立刻停止,

关闭打开的这个文件。在某种程度上减少 了build时间。一般用法:

#ifndef

#define

#pragma   once

.....

#endif

四. #pragma   data_seg(".mdata").....#pragma data_seg()可以让编译器把两者之间

的所有已初始化变量放入一个新的.mdata段中。应用之一是单应用程序。

有的时候我们可能想让一个应用程序只启动一次,就像单件模式(singleton)一样,实现的方法可能有多种,这里说说用#pragma data_seg的实现,很是简洁便利。

应用程序的入口文件前面加上:

#pragma data_seg("flag_data")

int app_count = 0;

#pragma data_seg()

#pragma comment(linker,"/SECTION:flag_data,RWS")

然后程序启动的地方加上

if(app_count>0) // 如果计数大于0,则退出应用程序。

{

//MessageBox(NULL, "已经启动一个应用程序", "Warning", MB_OK);

//printf("no%d application", app_count);

return FALSE;

} app_count++;

总结:

1. #ifndef 由语言支持所以移植性好,#pragma 可以避免名字冲突

2. 调查一下<stdlib.h>和<iostream>等标准库, 用得都是#ifndef, 我个人推荐这种方式.

原文地址:http://blog.csdn.net/l5201314131413141314/article/details/34103367

pragma的更多相关文章

  1. #pragma once与#ifndef #define ...#endif的区别

    1. #pragma once用来防止某个头文件被多次include: #ifndef,#define,#endif用来防止某个宏被多次定义.   2. #pragma once是编译相关,就是说这个 ...

  2. 预处理指令#pragma

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

  3. 关于 Pragma 的使用总结

    注意:此文乃是本人阅读多个博客文章后,记下的个人认为重点的地方. 参考文章: 参考1   参考2 #Pragma mark - 用于分离类中的不同功能的方法.(例如,一个 viewController ...

  4. IAR #pragma vector 中断入口地址

    在IAR编译器里用关键字来__interrupt来定义一个中断函数.用#pragma vector来提供中断函数的入口地址. #pragma vector = 0x12    //定时器0溢出中断入口 ...

  5. #pragma pack(push,1)与#pragma pack(1)的区别

    这是给编译器用的参数设置,有关结构体字节对齐方式设置, #pragma pack是指定数据在内存中的对齐方式. #pragma pack (n)             作用:C编译器将按照n个字节对 ...

  6. 你可能不知道的iOS冷知识——#pragma

    Mattt Thompson撰写. Zihan Xu翻译. 发布于2012年10月1日 #pragma 声明是彰显 Objective-C 工艺的标志之一.虽然 #pragma 最初的目的是为了使得源 ...

  7. 关于#pragma once和#ifndefine组合的区别

    最近在看duilib代码,发现头文件既有#pragma once 又有 #ifndefine...#define,忽然就觉得有点不解,因为据我所知这两者都是防止头文件二次包含的. 经过下面两位的解释后 ...

  8. Pragma如何分组

    Pragma Pragma Mark #pragma mark - 是一个在类内部组织代码并且帮助你分组方法实现的好办法. 我们建议使用 #pragma mark - 来分离: 不同功能组的方法 pr ...

  9. 【C语言】pragma

    ① #pragma comment (lib, "libgsl.a") 这是告诉编译器在编译形成的.obj文件和.exe文件中加一条信息,使得 链接器在链接库的时候要去找libgs ...

随机推荐

  1. invoke

    在用.NET Framework框架的WinForm构建GUI程序界面时,如果要在控件的事件响应函数中改变控件的状态,例如:某个按钮上的文本原先叫“打开”,单击之后按钮上的文本显示“关闭”,初学者往往 ...

  2. Python全栈考试-部分试题(精选)

    Python全栈考试(一) Python全栈考试(一) 1.执行 Python 脚本的两种方式 答:1.>>python ../pyhton.py 2. >>python.py ...

  3. socket选项总结(setsocketopt)

    功能描述:        获取或者设置与某个套接字关联的选 项.选项可能存在于多层协议中,它们总会出现在最上面的套接字层.当操作套接字选项时,选项位于的层和选项的名称必须给出.为了操作套接字层的选项, ...

  4. ORACLE分区--表分区

    .love_flying_snow Oracle表分区 Oracle . 废话少说,直接讲分区语法. Oracle表分区分为四种:范围分区,散列分区,列表分区和复合分区. 一:范围分区 就是根据数据库 ...

  5. Linux下MySQL数据库常用基本操作 一

    1.显示数据库 show databases; 2.选择数据库 use 数据库名; 3.显示数据库中的表 show tables; 4.显示数据表的结构 describe 表名; 5.显示表中记录 S ...

  6. Centos 7U盘安装

    1. 8G U盘 老毛桃软件 centos 7 everything.iso 7.4G左右 2.遇到问题 安装一刚开始 报错 unexpected exception  attribute error ...

  7. Maven Archetype

    1. 从project创建archetype 在项目根目录下,运行 mvn archetype:create-from-project 创建的archetype工程在app_folder/target ...

  8. [转载] Android随笔之——PackageManager详解

    本文转载自: http://www.cnblogs.com/travellife/p/3932823.html 参考:http://www.cnblogs.com/xingfuzzhd/p/33745 ...

  9. C语言学习笔记(二)_system系统调用及posix说明

    1.9 System系统调用 System库函数的功能是执行操作系统的命令或者运行指定的程序.system库函数的调用需要#include<stdlib.h>这个头文件. #include ...

  10. 极光推送NotificationServiceTest.appex文件变红不存在丢失解决办法

    这个图片是文件丢失的 创建.appex文件 创建.appex文件 把极光demo里面的这两个文件复制粘贴到新的文件件(新创建的文件是 UIViewController类型的所以就把 (Notifica ...