pragma指令简介
来源:互联网 发布:fanuc铣孔螺旋下刀编程 编辑:程序博客网 时间:2024/04/30 20:19
本文转自:http://www.cnblogs.com/xmsnzs/articles/pragma.html
http://en.wikipedia.org/wiki/Pragma_once
pragma指令简介
在编写程序的时候,我们经常要用到#pragma指令来设定编译器的状态或者是指示编译器完成一些特定的动作。
一.message参数
message它能够在编译消息输出窗口中输出相应的消息,这对于源代码信息的控制非常重要的,使用方法为:
#pragma message(“消息文本”)
当编译器遇到这条指令时就在编译输出窗口中将消息文本打印出来。当我们在程序中定义了许多宏来控制源代码版本的时候,我们自己有可能都会忘记有没有正确的设置这些宏,此时我们可以用这条指令在编译的候进行检查,假设我们希望判断自己有没有源代码的什么地方定义了_X86这个宏可以用下面的方法:
#ifdef _x86
#pragma message("_x86 macro activated!")
#endif
当我们定义了_X86这个宏以后,应用程序在编译时就会在编译输出窗口里显示"_x86 macro activated!"。
二. 另一个使用得比较多的#pragma参数是code_seg。格式如:
#pragma code_seg([[{push|pop},][identifier,]]["segment-name"][,"segment-class"])
该指令用来指定函数在.obj文件中存放的节,观察OBJ文件可以使用VC自带的dumpbin命令行程序,函数在.obj文件中默认的存放节
为.text节
如果code_seg没有带参数的话,则函数存放在.text节中
push (可选参数) 将一个记录放到内部编译器的堆栈中,可选参数可以为一个标识符或者节名
pop(可选参数) 将一个记录从堆栈顶端弹出,该记录可以为一个标识符或者节名
identifier (可选参数) 当使用push指令时,为压入堆栈的记录指派的一个标识符,当该标识符被删除的时候和其相关的堆栈中的记录将被弹出堆栈
"segment-name" (可选参数) 表示函数存放的节名
例如:
//默认情况下,函数被存放在.text节中
void func1() { // stored in .text
}
//将函数存放在.my_data1节中
#pragma code_seg(".my_data1")
void func2() { // stored in my_data1
}
//r1为标识符,将函数放入.my_data2节中
#pragma code_seg(push, r1, ".my_data2")
void func3() { // stored in my_data2
}
int main() {
}
三. #pragma once(比较常用)
这是一个比较常用的指令,只要在头文件的最开始加入这条指令就能够保证头文件被编译一次
#pragma once用来防止某个头文件被多次include,#ifndef,#define,#endif用来防止某个宏被多次定义。
#pragma once是编译相关,就是说这个编译系统上能用,但在其他编译系统不一定可以,也就是说移植性差,不过现在基本上已经是每个编译器都有这个定义了。
#ifndef,#define,#endif这个是C++语言相关,这是C++语言中的宏定义,通过宏定义避免文件多次编译。所以在所有支持C++语言的编译器上都是有效的,如果写的程序要跨平台,最好使用这种方式
四. #pragma hdrstop表示预编译头文件到此为止,后面的头文件不进行预编译。
BCB可以预编译头文件以加快链接的速度,但如果所有头文件都进行预编译又可能占太多磁盘空间,所以使用这个选项排除一些头文件。
有时单元之间有依赖关系,比如单元A依赖单元B,所以单元B要先于单元A编译。你可以用#pragma startup指定编译优先级,
如果使用了#pragma package(smart_init) ,BCB就会根据优先级的大小先后编译。
五. #pragma warning指令
该指令允许有选择性的修改编译器的警告消息的行为
指令格式如下:
#pragma warning( warning-specifier : warning-number-list [; warning-specifier : warning-number-list...]
#pragma warning( push[ ,n ] )
#pragma warning( pop )
主要用到的警告表示有如下几个:
once:只显示一次(警告/错误等)消息
default:重置编译器的警告行为到默认状态
1,2,3,4:四个警告级别
disable:禁止指定的警告信息
error:将指定的警告信息作为错误报告
如果大家对上面的解释不是很理解,可以参考一下下面的例子及说明
#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)
在使用标准C++进行编程的时候经常会得到很多的警告信息,而这些警告信息都是不必要的提示,
所以我们可以使用#pragma warning(disable:4786)来禁止该类型的警告
在vc中使用ADO的时候也会得到不必要的警告信息,这个时候我们可以通过
#pragma warning(disable:4146)来消除该类型的警告信息
六. pragma comment(...)
该指令的格式为
#pragma comment( "comment-type" [, commentstring] )
该指令将一个注释记录放入一个对象文件或可执行文件中,
comment-type(注释类型):可以指定为五种预定义的标识符的其中一种
五种预定义的标识符为:
compiler:将编译器的版本号和名称放入目标文件中,本条注释记录将被编译器忽略
如果你为该记录类型提供了commentstring参数,编译器将会产生一个警告
例如:#pragma comment( compiler )
exestr:将commentstring参数放入目标文件中,在链接的时候这个字符串将被放入到可执行文件中,
当操作系统加载可执行文件的时候,该参数字符串不会被加载到内存中.但是,该字符串可以被
dumpbin之类的程序查找出并打印出来,你可以用这个标识符将版本号码之类的信息嵌入到可
执行文件中!
lib:这是一个非常常用的关键字,用来将一个库文件链接到目标文件中
常用的lib关键字,可以帮我们连入一个库文件。
例如:
#pragma comment(lib, "user32.lib")
该指令用来将user32.lib库文件加入到本工程中
linker:将一个链接选项放入目标文件中,你可以使用这个指令来代替由命令行传入的或者在开发环境中
设置的链接选项,你可以指定/include选项来强制包含某个对象,例如:
#pragma comment(linker, "/include:__mySymbol")
你可以在程序中设置下列链接选项
/DEFAULTLIB
/EXPORT
/INCLUDE
/MERGE
/SECTION
这些选项在这里就不一一说明了,详细信息请看msdn!
user:将一般的注释信息放入目标文件中commentstring参数包含注释的文本信息,这个注释记录将被链接器忽略
例如:
#pragma comment( user, "Compiled on " __DATE__ " at " __TIME__ )
补充一个
#pragma pack(n)
控制对齐 如
#pragma pack(push)
#pragma pack(1)
struct s_1{
char szname[1];
int a;
};
#pragma pack(pop)
struct s_2{
char szname[1];
int a;
};
则
printf("s_1 size : %d\n", sizeof(struct s_1));
printf("s_2 size : %d\n", sizeof(struct s_2));
得到5,8。
pragma once wiki
http://en.wikipedia.org/wiki/Pragma_once
From Wikipedia, the free encyclopedia
In the C and C++ programming languages, #pragma once is a non-standard but widely supported preprocessor directive designed to cause the current source file to be included only once in a single compilation. Thus, #pragma once
serves the same purpose as #include
guards, but with several advantages, including: less code, avoiding name clashes, and sometimes improved compile speed.[1]
Contents
[hide]- 1 Example
- 2 Advantages and disadvantages
- 3 Portability
- 4 Notes
- 5 External links
[edit]Example
See the article on #include
guards for an example of a situation in which one or the other of these methods must be used. The solution using include guards is given on that page; the #pragma once
solution would be:
- File "grandparent.h"
#pragma once struct foo { int member;};
- File "parent.h"
#include "grandparent.h"
- File "child.c"
#include "grandparent.h"#include "parent.h"
[edit]Advantages and disadvantages
Using #pragma once
instead of include guards will typically increase compilation speed since it is a higher-level mechanism; the compiler itself can compare filenames or inodes without having to invoke the C preprocessor to scan the header for #ifndef
and #endif
.
Common compilers such as GCC, Clang, and EDG-based compilers include special speedup code to recognize and optimize the handling of include guards, and thus little or no speedup benefit is obtained from the use of #pragma once
.[2][3][4]
Again because the compiler itself is responsible for handling #pragma once
, it is not necessary for the programmer to create new macro names such as GRANDPARENT_H
in the Include guard article's example. This eliminates the risk of name clashes, meaning that no header file can fail to be included at least once.
However, this high-level handling is not perfect; the programmer must rely on the compiler to handle #pragma once
correctly. If the compiler makes a mistake, for example by failing to recognize that two symbolic links with different names point to the same file, then the compilation will fail. Compilers with #pragma once
-related bugs included LCC-Win32 as of 2004[citation needed][5][6] and GCC as of 1998.[7] GCC originally gave a warning declaring #pragma once
"obsolete" when compiling code that used it. However, with the 3.4 release of GCC, the #pragma once
handling code was fixed to behave correctly with symbolic and hard links. The feature was "un-deprecated" and the warning removed.[8][9]
Both #pragma once
and include guards can be used to write portable code that can also take advantage of the #pragma once
optimization if the compiler supports it:
- File "grandparent.h"
#pragma once#ifndef GRANDPARENT_H#define GRANDPARENT_H struct foo{ int member;}; #endif /* GRANDPARENT_H */
[edit]Portability
[edit]Notes
- pragma指令简介
- pragma指令简介
- pragma指令简介
- pragma指令简介
- pragma指令简介
- pragma指令简介
- pragma指令简介
- pragma指令简介
- pragma指令简介
- pragma指令简介
- pragma指令简介
- pragma指令简介
- pragma指令简介
- pragma指令简介
- pragma指令简介
- pragma指令简介
- pragma指令简介
- pragma指令简介
- selenium RC 点击,报错:The error message is: 没有权限
- shell 脚本学习之判断条件
- wince 平台建立笔记
- 为KGDB 增加watchpoint断点支持 on x86
- C# WP7 23种设计模式汇总
- pragma指令简介
- Google对TCP快速恢复算法的改进
- 【phpcms-v9】phpcms-v9中首页、频道页、列表页如何显示文章的浏览量和评论数
- C#基本语法 - 基本的数据类型
- SQL Server 2012 各版本功能比较
- HDMI之CEC通道
- mysql books
- AJAX学习体会与问题
- #pragma once