【问题标题】:can't understand a macro definition (casting constant number to a class pointer)无法理解宏定义(将常量转换为类指针)
【发布时间】:2016-06-11 06:39:41
【问题描述】:

在代码中,我看到下面定义的宏我无法理解。

#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
  &reinterpret_cast<NetParameter*>(16)->f) - \
   reinterpret_cast<char*>(16))

宏名似乎是在计算类结构中字段 f 的偏移量。它的形式是从一个字段的地址中减去起始地址。这里如何使用 16 号?并且 deosn't reinterpret_case 仅适用于 16?(不是 16 -> f)。 如果有人请向我解释这段代码,我将不胜感激。

【问题讨论】:

  • 它似乎是在“想象”一个位于通用地址 16 的 NetParameter 对象,只是为了计算 f 字段的偏移量。我完全反对这种黑客行为。
  • @MarcoA。但为什么是 16?为什么不是 0。在某些情况下,这种“黑客”也是完全合法的。 en.cppreference.com/w/cpp/types/offsetof
  • @xaxxon 我的问题也是如此。我猜不是 0 是为了避免空指针问题,但是为什么不是 8 或 32?
  • 优先使用旧标准(POSIX.1-2001、POSIX.1-2008、C89、C99)的offsetof marco而不是OFFSET_OF_FIELD_

标签: c++ macros


【解决方案1】:

(现已重构)protobuf 标头(链接here)中的注释解释了它

// Note that we calculate relative to the pointer value 16 here since if we
// just use zero, GCC complains about dereferencing a NULL pointer.  We
// choose 16 rather than some other number just in case the compiler would
// be confused by an unaligned pointer.
#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD)    \
  static_cast<int>(                                           \
      reinterpret_cast<const char*>(                          \
          &reinterpret_cast<const TYPE*>(16)->FIELD) -        \
      reinterpret_cast<const char*>(16))
#endif

所以使用 16 的原因有两个:

  • 避免使用 NULL 指针
  • 使用对齐的指针

请注意,这是known to create some issues(在支持的情况下可以替换为__builtin_offsetof)。

【讨论】:

  • 哦,我明白了,事实上,我错过了第二个 reinterpret_cast 仅适用于 (16)。现在很清楚了。谢谢!
猜你喜欢
  • 1970-01-01
  • 2016-07-26
  • 1970-01-01
  • 2013-02-20
  • 1970-01-01
  • 2021-09-20
  • 1970-01-01
  • 2019-08-21
相关资源
最近更新 更多