1. #pragma once和#ifndef
C++在头文件被多次include时,会出现链接时重定义错误。(一个名称对应多个地址)
#pragma once和#ifndef用来防止头文件被多次include。
1)使用方式
#ifndef __CJJ_H__
#define __CJJ_H__
..... //声明、定义语句
#endif
#pragma once
.... //声明、定义语句
2)两者特点
2.1)#ifndef
它不仅可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件(或者代码段)不会被不小心同时包含。
缺点是如果不同头文件中的宏不小心”相同“,可能会导致”头文件存在,但由于#ifndef筛选过后,后包含的撞名头文件不被编译器实际包含“。
由于编译器每次都需要打开头文件才能判定是否有重复定义,因此在编译大型项目时,#ifndef会使得编译时间相对较长,因此开始支持#pragma once方式。
2.2)#pragma once
#pragma once一般由编译器提供保证:同一个文件不会被包含多次。注意这里所说的”同一个文件“是指物理上的一个文件,而不是内容相同的两个文件。
无法对一个头文件中的一段代码作#pragma once声明,而只能针对文件。
好处是,不用担心宏名冲突。对应的缺点就是如果某个头文件有多份拷贝,本方法不能保证它们不被重复包含。当然,相比宏名冲突引发的”找不到声明“的问题,这种重复包含很容易被发现并修正。
此外,#pragma once不支持跨平台。
2. #pragma指令(转载于:https://www.cnblogs.com/fnlingnzb-learner/p/5854494.html)
只记下常用的。
#pragma作用是设定编译器的状态或者是指示编译器完成一些特定的动作。#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的情况下,给出主机或操作系统专有的特征。依据定义,编译指示是机器或操作系统专有的,且对于每个编译器都是不同的。
格式:#pragma para。para参数可取:
1)message参数
#pragma message("消息文本")
当编译器遇到这条指令时就在编译输出窗口中将消息文本打印出来。
2)code_seg参数
#pragma code_seg( ["section-name" [, "section-class"] ])
它能设置程序中函数代码存放的代码段,用于驱动程序开发中。
3)#pragma once
保证物理上唯一的头文件最多被包含一次。兼容性较差。
4)#pragma
5)#pragma resource "*.dfm"
表示把*.dfm文件中的资源加入工程。
6)#pragma warning( disable:4507 34; once: 4385; error: 164)
不显示4507和34号警告错误,4385号警告信息仅报告一次,164号警告信息作为一个错误。
7)#pragma comment(...)
该指令将一个注释记录放入一个对象文件或可执行文件中。
#pragma comment( comment-type, ["commentstring"])
comment-type是一个预定义的标识符,指定注释的类型,应该是compiler, exestr, lib, linker之一。
commentstring是一个提供为comment-type提供附加信息的字符串。
常用的lib关键字,可以帮我们连入一个库文件。如:
#pragma comment( lib, "comctl32.lib")
linker关键字指定一个连接选项这样就不用在命令行输入或者在开发环境中设置了。只有下列linker选项能被传给linker:
/DEFAULTLIB, /EXPORT, /INCLUDE, /MANIFESTDEPENDENCY, /MERGE, /SECTION
8)#pragma pack
许多实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数k。
#pragma pack(n) //n一般是1、2、4、8或16
#pragma pack ( [ [ {push | pop }, ] [identifer,] ] [n] )
若不同的组件使用pack编译指示指定不同的紧凑对其,这个语法允许你把程序组件组合为一个单独的转换单元。
带push参量的pack编译指示的每次出现将当前的紧凑对齐存储到一个内部编译器堆栈中。