为什么优化标志会导致某些模板函数的链接器错误? [英] Why do optimisation flags cause linker errors for some template functions?

查看:100
本文介绍了为什么优化标志会导致某些模板函数的链接器错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个问题,其中一个应用程序在调试模式下编译良好,所有优化关闭。
但是我编译的版本,它打印出未解决的链接错误。



有问题的功能如下:

  template< typename T> 
T& Block :: val(size_t offset)
{
return *(reinterpret_cast< T *>(_ data + offset));
}

template< typename T>
const T& Block :: val(size_t offset)const
{
return *(reinterpret_cast< T *
}

而且我得到的错误都是:

 未定义引用unsigned long long& Block :: val< unsigned long long>(unsigned long)'

解决方案

通常不会将模板实现放在.cpp中,而是将.h或.inl包含在.h,它可能是.o的调试生成与它导出的符号更宽松。



运行 nm 在调试和发布版本的.o和diff的符号。



由于单一定义规则,模板在链接器是不寻常的。当涉及模板,其中主体在标题中,这导致多个等效定义,每个翻译单元一个。链接器允许他们直到最后一刻,它任意选择一个并丢弃其他。



我猜这里,但我怀疑,当你编译没有优化主体被视为正常,但是当优化时,编译器花费一些额外的努力来确定该主体在其他翻译单元中不可见,并拒绝导出。



查找外部模板。 / p>

I have a problem where an app compiles fine in debug mode with all optimization turned off. But the moment I compile for release it prints out unresolved link errors.

The functions in question are the following:

template <typename T>
T & Block::val(size_t offset) 
{
    return *(reinterpret_cast<T*>(_data + offset)); 
}

template <typename T>
const T & Block::val(size_t offset) const 
{ 
    return *(reinterpret_cast<T*>(_data + offset)); 
}

And the errors I'm getting all look like:

undefined reference to `unsigned long long& Block::val<unsigned long long>(unsigned long)'

What might be causing this?

解决方案

You normally wouldn't put template implementations in a .cpp but rather a .h or .inl which is included from a .h, it could be that the debug build of the .o is more liberal with the symbols it exports.

Run nm on the debug and release builds of the .o and diff the symbols.

Templates are unusual in linkers because of the One Definition Rule. When it comes to templates, where the body is in the header, this results in multiple equivalent definitions, one for each translation unit. The linker lets them all be until the last moment, where it selects one arbitrarily and discards the others.

I am guessing here, but I suspect that when you compile without optimisations the body is treated like normal, but when optimisations are on the compiler spends a bit of extra effort determining that this body is not visible in other translation units and declines to export it.

Look up extern templates.

这篇关于为什么优化标志会导致某些模板函数的链接器错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆