2016-10-03 58 views
7

考慮下面的代碼:不一致的行爲與GCC與的sizeof

#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 = ...和​​在main()編譯正常。

這是MSVC中的錯誤,還是我錯過了一些基本的東西?

+0

我看不出爲什麼它不應該工作。所以我會在一定程度上相信這是一個VS錯誤。 – bolov

+0

由於這些編譯器和編譯器問題在這裏很受歡迎,我們來打開池: – bolov

+6

A)它是一個VS bug – bolov

回答

5

這是MSVC中的一個錯誤。

C++ 11/14允許在非評估的上下文中使用非靜態類成員,請參見5.1.1 [expr.prim.general] p。 13:

一個ID表達式表示只能用於一類的非靜態數據成員或非靜態成員函數:

...

(13.3) - 如果該id表達式表示一個非靜態數據成員,它出現在一個未評估的操作數中。

[實施例:

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

- 端示例]

編輯:它看起來像MSVC接受B::M並且不接受A::B::M,這是一個完全無法解釋的行爲。我不明白它可能是什麼,但一個錯誤。

在C++ 11和C++ 14模式中,clang ++像g ++一樣接受程序。在C++ 03模式中,clang ++會拒絕所有4個引用到M(C++ 03沒有像13.3那樣的東西),而在C++ 03模式下的g ++仍然接受它們(這可能是一個g ++ C++ 03模式錯誤)。

相關問題