在不使用pragma的情况下禁用C中的结构填充

Man*_*anu 11 c pragma

如何在不使用pragma的情况下禁用C中的结构填充?

pax*_*blo 16

没有标准的方法可以做到这一点.该标准规定填充可以由实现自行决定.从C99 6.7.2.1 Structure and union specifiers第12段:

结构或联合对象的每个非位字段成员以适合其类型的实现定义方式对齐.

话虽如此,你可以尝试一些事情.


第一个你已经打折,#pragma用来试图说服编译器不要打包.无论如何,这不是便携式的.也没有任何其他特定于实现的方法,但您应该检查它们,因为如果您确实需要此功能,可能需要这样做.


第二种是按从大到小的顺序对字段进行排序,例如所有long long类型后跟的是long1,然后是所有类型int,short最后是char类型.这通常会起作用,因为它通常是具有更严格的对齐要求的较大类型.再次,不便携.


第三,您可以将类型定义为char数组并转换地址以确保没有填充.但请记住,如果变量未正确对齐,某些体系结构将会变慢,而其他体系结构将失败(例如,引发BUS错误并终止进程).

最后一个进一步解释.假设您的结构具有以下顺序的字段:

char C; // one byte
int  I; // two bytes
long L; // four bytes
Run Code Online (Sandbox Code Playgroud)

使用填充,您可能会得到以下字节:

CxxxIIxxLLLL
Run Code Online (Sandbox Code Playgroud)

x填充在哪里.

但是,如果将结构定义为:

typedef struct { char c[7]; } myType;
myType n;
Run Code Online (Sandbox Code Playgroud)

你得到:

CCCCCCC
Run Code Online (Sandbox Code Playgroud)

然后你可以这样做:

int *pInt = &(n.c[1]);
int *pLng = &(n.c[3]);
int myInt = *pInt;
int myLong = *pLng;
Run Code Online (Sandbox Code Playgroud)

为你带来:

CIILLLL
Run Code Online (Sandbox Code Playgroud)

不幸的是,再次,不便携.


所有这些"解决方案"都依赖于您对编译器和底层数据类型的深入了解.