#pragma的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的情况下,给出主机或操作系统专有的特征。其格式一般为: #pragma Para。
1. #pragma pack(n)
先看看下面的微软面试题:
问程序的输入结果是什么?#include <iostream.h> #pragma pack(8) struct example1 { short a; long b; }; struct example2 { char c; example1 struct1; short e; }; #pragma pack() int main(int argc, char* argv[]) { example2 struct2; cout << sizeof(example1) << endl; cout << sizeof(example2) << endl; cout << (unsigned int)(&struct2.struct1) - (unsigned int)(&struct2) << endl; return 0; }
答案是:
8
16
4
下面就是解答:
1 自然对界
struct 是一种复合数据类型,其构成元素既可以是基本数据类型(如int、long、float 等)的变量,也可以是一些复合数据类型(如array、struct、union 等)的数据单元。对于结构体,编译器会自动进行成员变量的对齐,以提高运算效率。缺省情况下,编译器为结构体的每个成员按其自然对界(natural alignment)条件分配空间。各个成员按照它们被声明的顺序在内存中顺序存储,第一个成员的地址和整个结构的地址相同。
例如:
struct naturalalign { char a; short b; char c; };
在上述结构体中,size 最大的是short,其长度为2 字节,因而结构体中的char 成员a、c 都以2 为单位对齐,sizeof(naturalalign)的结果等于6;
如果改为:
struct naturalalign { char a; int b; char c; };
其结果显然为12。
2 指定对界
一般地,可以通过下面的方法来改变缺省的对界条件:
使用伪指令#pragma pack (n),编译器将按照n 个字节对齐;
使用伪指令#pragma pack (),取消自定义字节对齐方式。
注意:如果#pragma pack (n)中指定的n 大于结构体中最大成员的size,则其不起作用,结构体仍然按照size 最大的成员进行对界。