正如您已经发现__attribute__
扩展仅适用于结构的成员,因此每个成员都应该单独应用它。这是您的代码稍作修改,使用tcc
0.9.26 编译,然后以正确的输出运行:
typedef struct {
char c __attribute__((packed));
unsigned short i __attribute__((packed));
char d __attribute__((packed));
} test_t;
int main(void)
{
test_t x;
printf("%zu\n", sizeof(test_t));
x.c = 0xCC;
x.i = 0xAABB;
x.d = 0xDD;
const char *s = (const char *) &x;
unsigned i;
for (i = 0; i < sizeof(x); i++)
printf("%3u %x\n", i, 0xFF & s[i]);
return 0;
}
结果:
4
0 cc
1 bb
2 aa
3 dd
这里有一个问题。正如您可能已经发现的那样,没有标题。正确编写的代码应具有:
#include <stdio.h>
#include <stdint.h> // then replace unsigned short with uint16_t
但是,使用标题__attribute__
不再起作用。我不确定这是否总是会发生,但在我的系统(CentOS 6)上,它确实是这样的。
正如我发现的解释在于内部sys/cdefs.h
标题,其中包含:
/* GCC has various useful declarations that can be made with the
`__attribute__' syntax. All of the ways we use this do fine if
they are omitted for compilers that don't understand it. */
#if !defined __GNUC__ || __GNUC__ < 2
# define __attribute__(xyz) /* Ignore */
#endif
所以__attribute__
类似函数的宏对于 来说是“洗牌的” tcc
,因为它没有定义__GNUC__
宏。tcc
开发人员和标准库(此处glibc
)编写者之间似乎有些不一致。