2015-03-31 44 views
3

這個gcc是過於好,做了開發認爲它會做的事情,或者是鏗鏘的東西過於挑剔。我缺少標準的一些微妙的規則,其中鐺是在抱怨這個鏗鏘:錯誤:無效使用非靜態數據成員

或者我應該使用的代碼的第二位,它基本上是offsetof是如何工作的

[[email protected] ~]$ g++ -Wall -pedantic -ansi a.cc 
[[email protected] ~]$ a.out 
50 
[[email protected] ~]$ cat a.cc 
#include <iostream> 

struct Foo 
{ 
    char name[50]; 
}; 

int main(int argc, char *argv[]) 
{ 
    std::cout << sizeof(Foo::name) << std::endl; 
    return 0; 
} 


[[email protected] ~]$ clang++ a.cc 
a.cc:10:29: error: invalid use of non-static data member 'name' 
    std::cout << sizeof(Foo::name) << std::endl; 
         ~~~~~^~~~ 
1 error generated. 
[[email protected] ~]$ g++ -Wall -pedantic -ansi b.cc 
[[email protected] ~]$ a.out 
50 
[[email protected] ~]$ cat b.cc 
#include <iostream> 

struct Foo 
{ 
    char name[50]; 
}; 

int main(int argc, char *argv[]) 
{ 
    std::cout << sizeof(static_cast<Foo*>(0)->name) << std::endl; 
    return 0; 
} 


[[email protected] ~]$ clang++ b.cc 
[[email protected] ~]$ a.out 
50 
+0

嗯,我發現添加-std = C++ 11停止它抱怨。所以現在我想知道哪個部分對於我用這個代碼違反的C++ 98。海灣合作委員會在任一版本都可以,但這並不意味着我沒有違反規則 – Adrian 2015-03-31 14:34:13

+0

不要通過添加評論來擴展你的問題。要麼回答你自己的問題,接受它問一個新的問題。或編輯您的問題,包括標題,並刪除不必要的部分。 – usr1234567 2015-03-31 14:52:13

回答

1

I found adding -std=c++11 stops it complaining. GCC is fine with it in either version.

現代GCC實際上是正確的版本甚至允許在-std=c++98模式下。但是,舊版本,如我的GCC 3.3.6,抱怨並拒絕編譯。

So now I wonder which part of C++98 I am violating with this code.

維基百科明確指出這樣的特徵的溶液中加入在C++ 11,並且是指N2253,它說的語法不被認爲通過最初的C++ 98標準無效,但然後故意澄清不允許這樣做(我不知道非靜態成員字段與其他數據類型的變量有什麼不同)。一段時間後,他們決定讓這個語法有效,但是直到C++ 11。

非常相同的文件提到一個醜陋的解決辦法,這也可以在整個網絡可見:

sizeof(((Class*) 0)->Field) 

它看起來像簡單地使用0NULLnullptr可能觸發空指針可能取消引用編譯器警告(儘管事實上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)sizeof Expression語法差異,因爲它們在形式上是不一樣的,甚至如果sizeof(Expression)有效 - 只要sizeof (Expression)有效。因此,最正確和最便攜的形式應該是sizeof(decltype(Expression)),但不幸的是它僅在C++ 11中可用;一些編制者長期提供typeof(Expression),但這從來不是標準的延伸。

相關問題