内联函数在链接期间发生冲突
Inlined functions colliding during linking?
我在头文件中定义了一个函数模板,并在几个源文件中使用了它。当我链接程序时,我得到以下错误:
Linking ....................... ./Release_gcc_lin64_5534_ST/tom
/mxhome/charrison/git/sdcore/libs/CommUtils/Release_gcc_lin64_5534_ST/libCommUtils.so(Block.o): In function `wd_sprintf_r(boost::basic_format<char, std::char_traits<char>, std::allocator<char> > const&)':
/mxhome/charrison/git/sdcore/libs/CommUtils/include/wd_sprintf.h:29: multiple definition of `wd_sprintf_r(boost::basic_format<char, std::char_traits<char>, std::allocator<char> > const&)'
./Release_gcc_lin64_5534_ST/tom.o:/mxhome/charrison/git/sdcore/libs/CommUtils/include/wd_sprintf.h:29: first defined here
/mxhome/charrison/git/sdcore/libs/CommUtils/Release_gcc_lin64_5534_ST/libCommUtils.so(MemRef.o): In function `wd_sprintf_r(boost::basic_format<char, std::char_traits<char>, std::allocator<char> > const&)':
/mxhome/charrison/git/sdcore/libs/CommUtils/include/wd_sprintf.h:29: multiple definition of `wd_sprintf_r(boost::basic_format<char, std::char_traits<char>, std::allocator<char> > const&)'
./Release_gcc_lin64_5534_ST/tom.o:/mxhome/charrison/git/sdcore/libs/CommUtils/include/wd_sprintf.h:29: first defined here
我不明白发生了什么事。假设函数是内联的,那么我如何防止跨对象文件的多个实例冲突?下面是包含函数定义的头文件:
wd_sprintf.h:
#ifndef WDSPRINTF_H
#define WDSPRINTF_H
#include <string>
#include <sstream>
#include <boost/format.hpp>
// This is what the recursive template function wd_sprintf_r devolves
// to..
std::string
wd_sprintf_r(const boost::format &boost_format) {
std::stringstream s;
s << boost_format;
return std::move(s.str()); // force move semantics
}
// wd_sprintf_r(format, args...):
//
// This unpacks the variadic arguments one at a time, recursively. It
// binds the first arg to the pattern, and if there are remaining
// variadic arguments, it calls itself. Otherwise it calls the above.
template <typename T, typename... Params>
std::string
wd_sprintf_r(boost::format &boost_format,
const T &arg, const Params&... parameters) {
return wd_sprintf_r(boost_format % arg, parameters...);
}
// wd_sprintf(pattern [,args...]):
//
// This creates a temporary boost::format from pattern, and calls
// wd_sprintf_r() to recursively extract and apply arguments.
#include <boost/exception/all.hpp>
class wd_sprintf_exception : public std::runtime_error {
public:
wd_sprintf_exception(std::string const& msg) : std::runtime_error(msg) {};
};
template <typename... Params>
std::string
wd_sprintf (const std::string &pat, const Params&... parameters) {
try {
boost::format boost_format(pat);
return wd_sprintf_r(boost_format, parameters...);
}
catch ( boost::io::format_error& e) {
const std::string what = std::string("wd_sprintf: ") + std::string(e.what());
throw wd_sprintf_exception(what);
}
}
#endif
函数模板不是问题-它们的定义必须出现在使用它们的每个翻译单元中(除非显式实例化),并且由编译器来安排它以使链接器满意。
但是,这里也有一个非模板函数,它遵循常规规则。您必须将其定义(= body)移动到源文件中,并仅在头文件中保留声明,或者将其定义保留在头文件中并标记为inline
。当标记为inline
时,它必须再次出现在使用它的每个翻译单元中(但这正是将要发生的事情),并且所有都将工作。
相关文章:
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- CMake-按正确顺序将项目与C运行时对象文件链接
- 从链接列表c++中删除一个项目
- 有根的二进制搜索树.保留与其父级的链接
- 读取文件的最后一行并输入到链接列表时出错
- 静态数据成员的问题-修复链接错误会导致编译器错误
- node-gyp 在 macOS 上未正确链接库
- 基于boost的程序的静态链接——zlib问题
- 协议缓冲区的静态链接会导致与现有符号冲突
- 在Linux(而不是OSX)中链接时发生库冲突
- 在链接的程序集文件中,我想从 c++ 调用代码访问变量.是否可以在不触发访问冲突的情况下执行此操作?
- 尝试解决链接器警告:默认库'MSVCRT'与使用其他库冲突
- 创建链接列表时发生访问冲突错误
- 链接 : 警告 LNK4098: 默认库 'MSVCRT' 与其他库的使用冲突;使用 /NODEFAULTLIB:Library
- 内存冲突:SIGSEGV 和"找不到虚拟表的链接器符号..."
- 链接时间优化与多线程支持冲突
- 依赖项上的c++动态链接可能会导致冲突
- 双链接列表中存在访问冲突
- c++:不同链接库中定义的相同函数的运行时冲突
- 内联函数在链接期间发生冲突