GCC 内存对其选项、警告、其他方式对其

*** gcc 对其选项 [-fpack-struct]

 gcc -fpack-struct[=n]

该编译器选项解决了结构中字节对齐问题。

-fpack-struct将所有结构成员无缝隙地压缩在一起。因为它使代码程序效率大大降低,且结构成员的偏移量与系统库不相符,这么做有时可能导致寻址错误,所以一般不使用这个选项。

原文:

-fpack-struct[=n]
Without a value specified, pack all structure members together without holes. When a value is specified (which must be a small power of two), pack structure members according to this value, representing the maximum
alignment (that is, objects with default alignment requirements larger than this are output potentially unaligned at the next fitting location.

Warning: the -fpack-struct switch causes GCC to generate code that is not binary compatible with code generated without that switch. Additionally, it makes the code suboptimal. Use it to conform to a non-default
application binary interface.

 

***gcc -Wpadded 检测字节是否对齐

#include<stdio.h>

struct my {

char *name;
int age;
} my_details;

int main() {
struct my person1;
return 0;
}

编译

gcc -Wpadded -fpack-struct=8 -o test /tmp/test.c

会收到警告,因为 int 4个字节。

 

*** 其他方式对齐

#ifdef __cplusplus
extern "C" {
#endif

// 以下代码是用来字节对齐使用的
#ifndef WIN32
#ifndef __GNUC__
#define __PACKED__
#pragma options align=packed
#else
#define __PACKED__ __attribute__ ((packed))
#pragma pack(push,1)
#endif
#else
#define __PACKED__
#pragma pack(push,1)
#endif

 

***********************

struct TestStruct4
{
char a;
long b;
};

***********************

 

#ifndef WIN32
#ifndef __GNUC__
#pragma options align=reset
#else
#pragma pack(pop)
#endif
#else
#pragma pack(pop)
#endif

 

#ifdef __cplusplus
}
#endif

或者:

#pragma pack(8)

struct TestStruct4
{
char a;
long b;
};

#pragma pack()

使用指令#pragma pack (n),编译器将按照n 个字节对齐。
使用指令#pragma pack (),编译器将取消自定义字节对齐方式。

但是文件一定要按照C的方式,使用 extern "C" {}选项。

 

**** 网上其他摘要

http://blog.chinaunix.net/uid-25808509-id-2426501.html?_t=t

注意别的#pragma pack 的其他用法:
#pragma pack(push) //保存当前对其方式到packing stack
#pragma pack(push,n) 等效于 #pragma pack(n)
#pragma pack(n) //n=1,2,4,8,16 保存当前对齐方式,设置按n 字节对齐
#pragma pack(pop) //packing stack 出栈,并将对其方式设置为出栈的对齐方

【pack 结果与 OS 相关】
默认的内存对齐方式以及内存对齐规则在不同的系统上是有区别的,所以GCC编译器在这一点上在不同的系统上也是区别对待的。
虽然到现在也没有看到GCC在Linux系统下的使用 #pragma pack(N) 的内存对齐规则,
但是从我测试的结果来看是这样:默认的对齐是按照 int 型(4字节)对齐,如果指定 #pragma pack(N) 中的 N 的话,N 不能大于默认对齐指定的长度,即如果默认对齐是 4 的话,N的取值可以是 1、2、4,超过 4 之后作为 4 处理。
在 Windows 等系统上似乎没有这个限制。

 

posted @ 2020-01-01 15:55  雪域蓝心  阅读(1199)  评论(0编辑  收藏  举报