0

我正在尝试#pragma pack通过 , 来实现指令_Pragma оperator,以创建用于数据结构对齐的宏。所有这一切都在“C: In a Nutshell”一书中进行了描述

#define  STR(s)  #s
#define  ALIGNMENT(n) _Pragma( STR (pack(n)) )
#define  ALIGNLEVEL(l) ALIGNMENT(l)
int  main()
{
   ....
    if(1)
    {
        ALIGNLEVEL(1)
        printf("%s\n", STR(Byte-aligned: no padding));>
    }
    else
    {
        ALIGNLEVEL(4)
        printf("%s\n", STR(four-byte: boundaries));

    }
    typedef struct s
    {
        size_t l_num;
        short  h_num;
        char ch;
    } s;

我期望的结果是我的结构大小等于7 个字节(字节对齐)或x64 位平台中的11 个字节。上面的代码是使用GCC 4.7.x编译的,带有-Werror选项,返回结果是8 个字节(32 位操作系统)。

这个宏有什么问题?
为什么会这样?

4

1 回答 1

2

您的程序是在假设编译指示受if语句测试评估结果影响的情况下编写的。情况并非如此:第二个 pragma 简单地覆盖第一个,并且结构包装对齐无条件设置为 4。如果您注释掉第二个ALIGNLEVEL,您将获得预期的结果(在 ia32 和 x86 上使用 gcc 4.8.1 测试-64)。

编译器忽略运行时构造是有道理的,例如if在查看固有的编译时编译指示时。即使您if有一个常量测试,它也可以很容易地更改为非常量,并且编译器将无法提供一致的结果。如果您在不同情况下需要不同的对齐方式,则必须使用预处理器:

#if SOME_CONDITION
    ALIGNLEVEL(1)
    printf("%s\n", STR(Byte-alligned: no padding));>
#else
    ALIGNLEVEL(4)
    printf("%s\n", STR(four-byte: boundaries));
#endif

如果您需要根据运行时条件使用不同的对齐方式,则必须根据精心选择的抽象定义这两种结构并在使用其中一种的代码之间切换。

于 2013-07-12T18:31:04.030 回答