我在生产环境中遇到了以下代码构造(但大大简化了)。
#include <iostream>
typedef struct
{
char entry[10];
}
inn_struct;
typedef struct
{
inn_struct directory;
}
out_struct;
struct test
{
static const int
ENTRY_LENGTH = (sizeof((static_cast<out_struct*>(0))->directory.entry)
/ sizeof((static_cast<out_struct*>(0))->directory.entry[0]));
};
int main()
{
test a;
std::cout << test::ENTRY_LENGTH;
}
现在不考虑它明显混淆的性质,因为它只是确定数组长度的旧C方式......我真的被static_cast
的{{1}}所困扰价值。这个代码可以接受吗?你能不能把c ++标准中的一些段落附加到你的回复中,告诉我(如果)为什么这段代码没问题呢?
答案 0 :(得分:4)
是的,这段代码完全可以接受。见§5.3.3/ 1(强调我的)。
sizeof运算符产生其操作数的对象表示中的字节数。操作数是表达式,它是未评估的操作数(第5条),或者是paranthesized type-id 。
表达式未被计算,因此对于取消引用空指针的方式没有问题。
另请注意,在C ++ 11中,您不需要跳过那个箍,并且可以直接引用具有sizeof的类成员,这要归功于§5/ 8(强调我的):
在某些情况下,未评估的操作数出现(5.2.8,5.3.3,5.3.7,7.1.6.2)。未评估未评估的操作数。未评估的操作数被视为完整表达式。 [注意:在未评估的操作数中,非静态类成员可能被命名为(5.1),对象或函数的命名本身不需要定义提供(3.2)。 - 结束记录]
和§5.1.1/ 13:
表示非静态数据成员或类的非静态成员函数的 id-expression 只能使用:
...
如果 id-expression 表示非静态数据成员,并且它出现在未评估的上下文中 [示例:
struct S {
int m;
};
int i = sizeof(S::m); // OK
int j = sizeof(S::m + 42); // OK
- 结束示例]