本文介绍了Clang:错误:无效使用非静态数据成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 这个GCC是太好了,做什么Dev认为它会做,或者ang叨对于某事过于lyly。我在标准中缺少一些微妙的规则,其中clang在抱怨这个时是正确的或者我应该使用代码的第二位,基本上是offsetof的工作原理 [adrian @ localhost〜] $ g ++ -Wall -pedantic -ansi a.cc [adrian @ localhost〜] $ a.out 50 [adrian @ localhost〜] $ 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; } [adrian @ localhost〜] $ clang ++ a.cc a.cc:10:29:错误:无效使用非静态数据成员'name' std :: cout<< sizeof(Foo :: name)<< std :: endl; ~~~~~ ^ ~~~ 1错误生成。 [adrian @ localhost〜] $ g ++ -Wall -pedantic -ansi b.cc [adrian @ localhost〜] $ a.out 50 [adrian @ localhost〜] $ 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; } [adrian @ localhost〜] $ clang ++ b.cc [adrian @ localhost〜] $ a.out 50 解决方案 现代GCC版本允许在 std = c ++ 98 模式。但是,旧版本,如我的GCC 3.3.6, 抱怨并拒绝编译。维基百科明确指出, C ++ 11,并参考 N2253 ,这说明语法最初不被C ++ 98标准视为无效,但随后有意地澄清为不允许这一点(我不知道非静态成员字段与其他变量在数据方面有什么不同)类型)。一段时间后,他们决定使这个语法有效,但是直到C ++ 11。 同一个文档提到了一个丑陋的解决方法,这也可以在整个web: sizeof((Class *)0) - > Field) 看起来就像使用 0 , NULL 或 nullptr 可能会触发编译器警告可能取消引用空指针(尽管事实上 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 //使用`nullptr`可能会触发警告。 #define CxxSizeOf(TYPE,FIELD)(sizeof(reinterpret_cast< const TYPE *>(1234) - > FIELD)) #endif pre> 使用示例: //在块级别: 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 //函数内部: void Foo(void){ size_t nSize = CxxSizeOf(SomeHeader,Flags); } // end function Foo(void) 顺便说一句,注意 sizeof(Type)和 sizeof Expression 的语法差异,因为它们在形式上不一样, code> sizeof(Expression)工程 - 只要 sizeof(Expression)有效。因此,最正确和可移植的形式是 sizeof(decltype(Expression)),但不幸的是它只能在C ++ 11中使用;一些遵从者提供 typeof(Expression)很长时间,但这从来不是标准扩展。 Is this gcc being overly nice and doing what the dev thinks it will do or is clang being overly fussy about something. Am I missing some subtle rule in the standard where clang is actually correct in complaining about thisOr should I use the second bit of code which is basically the how offsetof works [adrian@localhost ~]$ g++ -Wall -pedantic -ansi a.cc[adrian@localhost ~]$ a.out50[adrian@localhost ~]$ 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;}[adrian@localhost ~]$ clang++ a.cca.cc:10:29: error: invalid use of non-static data member 'name' std::cout << sizeof(Foo::name) << std::endl; ~~~~~^~~~1 error generated.[adrian@localhost ~]$ g++ -Wall -pedantic -ansi b.cc[adrian@localhost ~]$ a.out50[adrian@localhost ~]$ 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;}[adrian@localhost ~]$ clang++ b.cc[adrian@localhost ~]$ a.out50 解决方案 Modern GCC versions allow this even in -std=c++98 mode. However, older versions, like GCC 3.3.6 of mine, do complain and refuse to compile.Wikipedia explicitly states that such a feature was added in C++11, and refers to N2253, which says that the syntax was not considered invalid by the C++98 standard initially, but then intentionally clarified to disallow this (I have no idea how non-static member fields are any different from other variables with regard to their data type). Some time later they decided to make this syntax valid, but not until C++11.The very same document mentions an ugly workaround, which can also be seen throughout the web:sizeof(((Class*) 0)->Field)It looks like simply using 0, NULL or nullptr may trigger compiler warnings for possible dereference of a null pointer (despite the fact that sizeof never evaluates its argument), so an arbitrary non-zero value might be used instead, although it will look like a counter-intuitive "magic constant". Therefore, in my C++ graceful degradation layer I use:#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))#endifUsage examples:// 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)By the way, note the syntax difference for sizeof(Type) and sizeof Expression, as they are formally not the same, even if sizeof(Expression) works — as long as sizeof (Expression) is valid. So, the most correct and portable form would be sizeof(decltype(Expression)), but unfortunately it was made available only in C++11; some compliers have provided typeof(Expression) for a long time, but this never was a standard extension. 这篇关于Clang:错误:无效使用非静态数据成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
05-27 21:33
查看更多