MSVC与GCC的行为不一致的sizeof

时间:2016-10-03 13:08:45

标签: c++ visual-c++ compiler-bug visual-c++-2015

请考虑以下代码:

#include <cstddef>

class A
{
public:
    struct B
    {
        int M;
    };

    static void StaticFunc();
};

void A::StaticFunc()
{
    const std::size_t s0 = sizeof(::A::B::M);
    const std::size_t s1 = sizeof(A::B::M);
    const std::size_t s2 = sizeof(B::M);
}

int main()
{
    const std::size_t s3 = sizeof(A::B::M);
    return 0;
}

GCC compiles it,只是警告未使用的变量。

然而,

Visual C ++ 2015无法使用以下代码编译它:

error C2326: 'void A::StaticFunc(void)': function cannot access 'A::B::M'

就行了

const std::size_t s0 = sizeof(::A::B::M);
const std::size_t s1 = sizeof(A::B::M);
StaticFunc()中的

s2 = ...中的另一行s3 = ...main()编译正常。

这是MSVC中的错误,还是我错过了一些基本的东西?

1 个答案:

答案 0 :(得分:5)

这是MSVC中的一个错误。

C ++ 11/14允许在非评估的上下文中使用非静态类成员,参见5.1.1 [expr.prim.general] p。 13:

  

表示非静态数据成员或类的非静态成员函数的id表达式只能用于:

     

...

     

(13.3) - 如果该id-expression表示非静态数据成员,并且它出现在未评估的操作数中。

     

[例如:

    struct S {
       int m;
    };
    int i = sizeof(S::m);        // OK
    int j = sizeof(S::m + 42);   // OK
     

- 结束示例]

编辑:看起来MSVC接受B::M并且不接受A::B::M,这是一种完全无法解释的行为。我不知道除了一个错误之外它是怎么回事。

clang ++ like g ++ in C ++ 11 and C ++ 14 mode接受该程序。 c ++ 03模式下的clang ++拒绝所有4个M的引用(C ++ 03没有像第13.3页那样),而C ++ 03模式中的g ++仍然接受它们(这可能是g ++ C ++ 03模式bug)。