【问题标题】:offsetof at compile time编译时的偏移量
【发布时间】:2009-09-04 13:33:08
【问题描述】:

有没有办法在编译时找到结构成员的偏移量?我希望创建一个包含结构成员偏移量的常量。在下面的代码中,offsetof() 宏在第一个 printf 语句中起作用。但是,使用第 10 行声明 ofs 会产生错误:

“无法将 '->' 运算符解析为常量表达式”。

还有其他方法吗?

struct MyStruct
{
   unsigned long lw;
   unsigned char c[5];
   int i;
   int j;
   unsigned long last;
};

const int ofs = offsetof(struct MyStruct, i);  // This line in error

int main(void)
{
   printf("Offset of c = %d.\n", offsetof(struct MyStruct, c) );
   printf("Offset of i = %d.\n", ofs );
   return 0;
}

【问题讨论】:

    标签: c struct macros c-preprocessor offsetof


    【解决方案1】:

    offsetof() 宏 一个编译时构造。没有符合标准的方式来定义它,但是每个编译器都必须有某种方式来定义它。

    一个例子是:

    #define offsetof( type, member ) ( (size_t) &( ( (type *) 0 )->member ) )
    

    虽然不是编译时构造技术上(参见用户“litb”的cmets),但每个编译器必须至少有一个这样的表达式,它能够在编译时解析,这正是 中定义的 offsetof()

    您的代码可能存在其他错误 - 缺少包含,或者其他一些刺激编译器的事情。

    【讨论】:

    • 当然,这不是他所说的“编译时间”。您展示了一个不使用库函数的构造,但这并不意味着它评估为编译时值。当然,代码是否实际发出是无关紧要的——C 草案说“算术常量表达式应具有算术类型,并且只能具有整数常量、浮动常量、枚举常量、字符常量和表达式大小的操作数。”。混合中不允许使用指针。
    • offsetof 是一个编译时构造,计算结果为整数常量表达式,但您的示例实现不是。
    • 语言中有 NO 的方式将 offsetof() 定义为计算结果为整数常量表达式的东西。有 NO 方法可以在不使用指针的情况下定义它。无论您做什么,您都将始终依赖内置编译器和/或编译器的能力来适当地优化您的表达式。查看关于 offsetof 或任何开源 C 库的 Wikipedia。因此,虽然您在整数常量表达式的定义上在技术上是正确的(并且我调整了我的措辞),但您指责我的示例实现是错误的。
    • 值得一提的是,上述实现与 (glibc) ./resolv/nss_dns/dns-network.c 中的实现相同。
    • 我不仅指着你的示例实现,还指着你的示例实现,并附有“看,所有编译时间”。我知道该宏的实现可能有缺陷(发问者很可能只是遇到了这种有缺陷的实现)。我无法评论那个 c-files 宏,但如果它使用这样的东西并声称是“offsetof”的可移植替代品(我怀疑 - 因为文件看起来“官方”),那么它就是错误的 - 但它可能仍可用于目的。例如,GCC 的实现只调用“__builtin_offsetof”。
    【解决方案2】:

    在我添加正确的#includes 之后,它在此处使用 g++ 4 编译而不会发出警告。

    您是否#include stddef.h? offsetof() 是一个宏,不是 C 中的内置关键字。

    如果这不能解决问题,请尝试将常量设为静态,以将其限制在模块中。这可能会让编译器高兴。

    【讨论】:

      【解决方案3】:

      如果你有我假设的#include <stddef.h>(你引用的错误消息将毫无意义),这是你的编译器中的一个错误。 offsetof 结果是 C99 和 C90 中的整数常量表达式。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-12
        • 1970-01-01
        相关资源
        最近更新 更多