すでにわかっているように、__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
ここで 1 つのキャッチがあります。すでにお気づきかもしれませんが、ヘッダーはありません。正しく記述されたコードには次のものが必要です。
#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