我发现添加-std=c++11
停止抱怨。海湾合作委员会还不错
在任一版本中都有它。
现代 GCC 版本甚至在-std=c++98
模式。然而,旧版本,比如我的 GCC 3.3.6,do抱怨并拒绝编译。
所以现在我想知道这段代码违反了 C++98 的哪一部分。
维基百科明确指出 C++11 中添加了这样的功能,并提到N2253 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2253.html,它表示 C++98 标准最初并不认为该语法无效,但后来有意澄清不允许这样做(我不知道非静态成员字段在数据类型方面与其他变量有什么不同) 。一段时间后,他们决定使这种语法有效,但直到 C++11 才生效。
同一份文档提到了一个丑陋的解决方法,这也可以在整个网络上看到:
sizeof(((Class*) 0)->Field)
看起来就像简单地使用0
, NULL
or nullptr
可能会因可能取消引用空指针而触发编译器警告(尽管事实上sizeof
从不计算其参数),因此可以使用任意非零值来代替,尽管它看起来像一个反直觉的“魔法常量”。因此,在我的 C++ 优雅降级层中,我使用:
#if __cplusplus >= 201103L
#define CXX_MODERN 2011
#else
#define CXX_LEGACY 1998
#endif
#ifdef CXX_MODERN
#define CXX_FEATURE_SIZEOF_NONSTATIC
#define CxxSizeOf(TYPE, FIELD) (sizeof TYPE::FIELD)
#else
// Use of `nullptr` may trigger warnings.
#define CxxSizeOf(TYPE, FIELD) (sizeof (reinterpret_cast<const TYPE*>(1234)->FIELD))
#endif
用法示例:
// On block level:
class SomeHeader {
public:
uint16_t Flags;
static CxxConstExpr size_t FixedSize =
#ifdef CXX_FEATURE_SIZEOF_NONSTATIC
(sizeof Flags)
#else
sizeof(uint16_t)
#endif
;
}; // end class SomeHeader
// Inside a function:
void Foo(void) {
size_t nSize = CxxSizeOf(SomeHeader, Flags);
} // end function Foo(void)
顺便说一下,请注意语法差异sizeof(Type)
and sizeof Expression
,因为它们在形式上并不相同,即使sizeof(Expression)
有效——只要sizeof (Expression)
已验证。所以,最正确和可移植的形式是sizeof(decltype(Expression))
,但不幸的是它仅在 C++11 中可用;一些编译者提供了typeof(Expression)
很长一段时间了,但这从来都不是标准的扩展。