#pragma简介
- #pragma用于指示编译器完成一些特定的动作
- #pragma所定义的很多指示字都是编译器特有的
- #pragma在不同的编译器间是不可移植的
- 预处理器将忽略它不认识的#pragma指令
- 不同的编译器可能以不同的方式解释同一条#pragma指令
一般用法:
#pragma parameter
注:不同的parama参数语法和意义各不相同。
#pragma message
- message参数在大多数的编译器中都有相似的实现
- message参数在编译时输出消息到编译输出窗口中
- message用于条件编译中可提示代码版本信息
#if defined(ANDROID20)
#pragma message("Compile Android SDK 2.0...")
#define VERSION "Android 2.0"
#endif
与#error和#warning不同, #pragma message仅仅代表一条编译信息,不代表程序错误。
示例代码:#pragma message使用示例
#include <stdio.h>
#define ANDROID23
#if defined(ANDROID20)
#pragma message("Compile Android SDK 2.0...")
#define VERSION "Android 2.0"
#elif defined(ANDROID23)
#pragma message("Compile Android SDK 2.3...")
#define VERSION "Android 2.3"
#elif defined(ANDROID40)
#pragma message("Compile Android SDK 4.0...")
#define VERSION "Android 4.0"
#else
#error Compile Version is not provided!
#endif
int main()
{
printf("%s\n", VERSION);
return 0;
}
输出结果
ctest.c:8: note: #pragma message: Compile Android SDK 2.3…
#pragma once
- #pragma once用于保证头文件只被编译一次
- #pragma once是编译器相关的,不一定被支持
注:一般我们不使用这种方式,而是使用一下方式:
#ifndef _HEADER_FILE_H
#define _HEADER_FILE_H
//source code
#endif
#pragma pack
什么是内存对齐?
不同类型的数据在内存中按照一定的规则排列
而不一定是顺序的一个接一个的排列。
例如:以下Test1和Test2所占的内存空间是否相同?
实际上我们通过代码测试,Test1和Test2所占的内存空间是不相同的。那么它们在内存的分布是怎么样的呢?
为什么需要内存对齐?
- CPU对内存的读取不是连续的,而是分成块读取的,块的大小只能是1、2、4、8、16…字节
- 当读取操作的数据未对齐,则需要两次总线走起来访问内存,因此性能会大打折扣
- 某些硬件平台只能从规定的相对地址处读取特定类型的数据,否则产生硬件异常
如何进行内存对齐?
- #pragma pack用于指定内存对齐方式
- #pragma pack能够改变编译器的默认对齐方式
问题:那么sizeof(struct Test1) = ?; sizeof(struct Test2) = ?
示例代码:结构体大小计算
#include <stdio.h>
#pragma pack(2)
struct Test1
{
char c1;
short s;
char c2;
int i;
};
#pragma pack()
#pragma pack(4)
struct Test2
{
char c1;
char c2;
short s;
int i;
};
#pragma pack()
int main()
{
printf("sizeof(Test1) = %d\n", sizeof(struct Test1));
printf("sizeof(Test2) = %d\n", sizeof(struct Test2));
return 0;
}
输出结果:
sizeof(Test1) = 10
sizeof(Test2) = 8
内存对齐到底是如何计算的呢?
- 第一个成员起始于0偏移处
- 每个成员按其类型大小和pack参数中较小的一个进行对齐
- 偏移地址必须能被对齐参数整除
- 结构体成员的大小取其内部长度最大的数据成员作为其大小
- 结构体总长度必须为所有对齐参数的整数倍
编译器在默认情况下按照4字节对齐。