2015-03-31 96 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),但这从来不是标准的延伸。

相关问题