C++ 从GCC 4.6更改为4.7时未定义的参考
我不得不从g++-4.6切换到4.7(这样我就可以使用一些C++11特性)。现在,编译器抱怨: 函数WordJIT::WordJIT()中的C++ 从GCC 4.6更改为4.7时未定义的参考,c++,static,c++11,constants,C++,Static,C++11,Constants,我不得不从g++-4.6切换到4.7(这样我就可以使用一些C++11特性)。现在,编译器抱怨: 函数WordJIT::WordJIT()中的:对JitRegType::Val\u t的未定义引用 我想知道这些编译器版本之间是否发生了影响符号解析的变化。还是在新版本(4.7)中更好地实现了该语言,而我所做的是错误的:(4.6编译的代码相同) 准时制 类Jit{ 公众: 枚举RegType{f32=0,f64=1,u16=2,u32=3,u64=4,s16=5,s32=6,s64=7}; // ..
:对JitRegType::Val\u t的未定义引用
我想知道这些编译器版本之间是否发生了影响符号解析的变化。还是在新版本(4.7)中更好地实现了该语言,而我所做的是错误的:(4.6编译的代码相同)
准时制
类Jit{
公众:
枚举RegType{f32=0,f64=1,u16=2,u32=3,u64=4,s16=5,s32=6,s64=7};
// ...
};
模板结构JitRegType{};
模板结构JitRegType{static const Jit::RegType Val_t=Jit::f32;};
wordjit.h
#包括“jit.h”
模板
类WordJIT
{
WordJIT(){
insert(std::make_pair(JitRegType::Val_t,jit.getRegs(JitRegType::Val_t,1));
}
私人:
typedef std::mapMapRegType;
可变MapRegType mapReg;
};
编辑:
头文件中的static const
正常吗,还是应该使用constepr
是否有方法在JitRegType
的类声明中声明Val\t
,但不实际定义它?根据9.4.2p3:
如果非易失性常量静态数据成员是整型或枚举类型,则其在类定义中的声明可以指定大括号或相等的初始值设定项[…]如果该成员在程序中使用odr,则仍应在命名空间范围中定义,且命名空间范围定义不应包含初始值设定项
因此,您需要添加到您的程序中(可能在jit.cpp
中):
const Jit::RegType JitRegType::Val\t;
这是因为,如果在需要引用的上下文中使用静态常量
成员,则链接器存在唯一的引用定义(与不是类模板或类模板部分专门化成员的任何静态
成员相同)
对这个问题进行了深入讨论
请注意,gcc 4.6和4.7的行为都是合理的;只是GCC4.6选择内联
JitRegType::Val_t
的值,而GCC4.7选择不内联(或者可能是内联它,但也会发出对定义的链接器引用)。判断是否需要实现来发布诊断代码有点困难;9.4.2p3描述了一个可诊断规则,但9.4.2p4(暗指非const
reg
inreg(JitRegType::Val\t)代码>?@PiotrNycz我将其替换为占位符,以避免过分夸大示例。但是,如上所述,您是否在切换到GCC4.7但仍停留在C++03时出现错误,或者您是否也启用了C++11?因为如果您选择了相同的C++标准版本,则应该在两个版本中实现名称解析,因为它们应该按照标准实现。<代码> -STD= C++ +0x在4.6和4.7中启用。我需要C++11在代码的其他部分的一般功能。现在我正在使用构造函数委托-切换到4.7肮脏解决方案的原因是:使reg(…)
接受int而不是RegType
,或者强制转换它。但是如果有人知道这在4.6中起作用而在4.7中不起作用的原因,那就更好了…@Frank gcc 4.6正在内联该值(它可以从标题访问该值),并且不发送对该值的链接器引用。严格地说,如果没有定义,您的程序是不正确的,即使GCC4.6编译了它。哇!这一点很重要。当切换到4.7时,可能会中断大量代码,显然4.7更严格地实现了该语言。非常感谢!!
class Jit {
public:
enum RegType { f32=0,f64=1,u16=2,u32=3,u64=4,s16=5,s32=6,s64=7 };
// ...
};
template <class T> struct JitRegType {};
template <> struct JitRegType<float> { static const Jit::RegType Val_t = Jit::f32; };
#include "jit.h"
template<class T>
class WordJIT
{
WordJIT() {
mapReg.insert( std::make_pair( JitRegType<T>::Val_t , jit.getRegs( JitRegType<T>::Val_t , 1 ) ) );
}
private:
typedef std::map< Jit::RegType , int > MapRegType;
mutable MapRegType mapReg;
};
const Jit::RegType JitRegType<float>::Val_t;