【问题标题】:Strange usage of static_caststatic_cast 的奇怪用法
【发布时间】:2015-01-08 12:56:21
【问题描述】:

我在我们的生产环境中遇到了以下代码结构(但是非常简化)。

#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 方法......我真的对 0 值的 static_cast 感到困扰。 ...这个代码可以接受吗?您能否在您的回复中附上一些来自 c++ 标准的段落,告诉我(如果)为什么这段代码可以?

【问题讨论】:

    标签: c++ null zero static-cast


    【解决方案1】:

    是的,这个代码是完全可以接受的。请参阅 §5.3.3/1(强调我的)。

    sizeof 运算符产生其操作数的对象表示中的字节数。操作数要么是一个表达式,它是一个未求值的操作数(第 5 条),要么是一个带括号的 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
    

    - 结束示例]

    【讨论】:

    • 关于更好的形式 (X::entry) 的两个注意事项:1. 它在 Clang 和 GCC 中有效,但在 Visual C++ 2013 中无效。 2. 更好的报价是[5.1.1]的结尾,这里还有一个例子。
    • @bogdan 也添加了该部分,第一次没有读到那么远。还有令人讨厌的格式:-/
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-05
    相关资源
    最近更新 更多