2

我正在尝试在 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)) 和其他一些测试 - 没有一个有效。

4

3 回答 3

2

正如您已经发现__attribute__ 扩展仅适用于结构的成员,因此每个成员都应该单独应用它。这是您的代码稍作修改,使用tcc0.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)编写者之间似乎有些不一致。

于 2015-02-21T17:08:50.490 回答
1

我可以确认至少在结构成员上使用 tcc 0.9.26属性((packed)) 不起作用。使用 Windows 风格的打包编译指示效果很好:

    #if defined(__TINYC__)
    #pragma pack(1)
    #endif

    typedef struct {
            uint16_t ..
    } interrupt_gate_descriptor_t;

    #if defined(__TINYC__)
    #pragma pack(1)
    #endif
于 2017-05-22T18:15:24.290 回答
0

似乎是 TCC 的错误。

根据许多来源,包括这个,http://wiki.osdev.org/TCC

这应该工作:

struct some_struct {
   unsigned char a __attribute__((packed));
   unsigned char b __attribute__((packed));
} __attribute__((packed));

...但它不起作用。

于 2015-02-20T21:26:02.287 回答