tcc 中的打包结构
packed structs in tcc
我正在尝试在 tcc C 编译器中执行打包结构。
代码如下,需要支持__attribute __标签:
#include <stdio.h>
#include <stdint.h>
typedef struct _test_t{
char c;
uint16_t i;
char d;
} __attribute__((__packed__)) test_t;
int main(){
test_t x;
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;
}
它在 gcc 中有效,但在 tcc 中无效。
我还尝试了 __attribute __((packed)) 和其他一些测试 - none 有效。
TCC 似乎出错了。
根据许多来源,包括这个,http://wiki.osdev.org/TCC
这应该有效:
struct some_struct {
unsigned char a __attribute__((packed));
unsigned char b __attribute__((packed));
} __attribute__((packed));
...但它不起作用。
如您所见,__attribute__
extension 仅适用于结构的成员,因此每个成员都应单独应用。这是您的代码,稍作修改,使用 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
这里有一个问题。您可能已经发现没有 header。正确编写的代码应该有:
#include <stdio.h>
#include <stdint.h> // then replace unsigned short with uint16_t
但是,对于 headers,__attribute__
不再有效。我不确定这种情况是否总是发生,但在我的系统 (CentOS 6) 上确实如此。
我发现解释在内部 sys/cdefs.h
header,其中包含:
/* 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__
function-like 宏是 "washed-up" for tcc
,因为它没有定义 __GNUC__
宏。 tcc
开发人员和标准库(此处 glibc
)编写者之间似乎有些不一致。
我可以确认至少在 tcc 0.9.26 attribute((packed)) 上
结构成员不起作用。使用 Windows-style packing pragmas 工作得很好:
#if defined(__TINYC__)
#pragma pack(1)
#endif
typedef struct {
uint16_t ..
} interrupt_gate_descriptor_t;
#if defined(__TINYC__)
#pragma pack(1)
#endif
我正在尝试在 tcc C 编译器中执行打包结构。 代码如下,需要支持__attribute __标签:
#include <stdio.h>
#include <stdint.h>
typedef struct _test_t{
char c;
uint16_t i;
char d;
} __attribute__((__packed__)) test_t;
int main(){
test_t x;
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;
}
它在 gcc 中有效,但在 tcc 中无效。 我还尝试了 __attribute __((packed)) 和其他一些测试 - none 有效。
TCC 似乎出错了。
根据许多来源,包括这个,http://wiki.osdev.org/TCC
这应该有效:
struct some_struct {
unsigned char a __attribute__((packed));
unsigned char b __attribute__((packed));
} __attribute__((packed));
...但它不起作用。
如您所见,__attribute__
extension 仅适用于结构的成员,因此每个成员都应单独应用。这是您的代码,稍作修改,使用 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
这里有一个问题。您可能已经发现没有 header。正确编写的代码应该有:
#include <stdio.h>
#include <stdint.h> // then replace unsigned short with uint16_t
但是,对于 headers,__attribute__
不再有效。我不确定这种情况是否总是发生,但在我的系统 (CentOS 6) 上确实如此。
我发现解释在内部 sys/cdefs.h
header,其中包含:
/* 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__
function-like 宏是 "washed-up" for tcc
,因为它没有定义 __GNUC__
宏。 tcc
开发人员和标准库(此处 glibc
)编写者之间似乎有些不一致。
我可以确认至少在 tcc 0.9.26 attribute((packed)) 上 结构成员不起作用。使用 Windows-style packing pragmas 工作得很好:
#if defined(__TINYC__)
#pragma pack(1)
#endif
typedef struct {
uint16_t ..
} interrupt_gate_descriptor_t;
#if defined(__TINYC__)
#pragma pack(1)
#endif