为啥下面的方法会得到内部链接?
Posted
技术标签:
【中文标题】为啥下面的方法会得到内部链接?【英文标题】:Why does the following method get internal linkage?为什么下面的方法会得到内部链接? 【发布时间】:2016-02-02 14:02:48 【问题描述】:我正在使用clang-3.6
并编译一个相当大的项目。经过大规模重构后,少数类中的少量看似随机的方法会导致如下警告:
warning: function 'namespace::X::do_something' has internal linkage but is not defined [-Wundefined-internal]
在链接器阶段,相同的功能也会显示为缺失。
这是X.hpp
中一个此类函数定义的匿名标头:
class X
// ...
void do_something(
foo::Foo& foo,
double a
double b,
double c,
uint8_t d,
const bar::Bar& bar,
int dw, int dh);
// ...
该功能在X.cpp
中正常实现。当Y.cpp
包含X.hpp
并包含x->do_something
时,会出现内部链接的警告。
如上定义的方法如何具有内部链接? 方法获取内部链接的所有情况是什么?
并且看到这个函数和其他函数,过去编译得很好,在重构过程中甚至没有被触及,什么样的副作用(包括顺序、类型 Foo 和 Bar)会导致方法切换到内部链接?
编辑:
当我对 do_something
进行完整的源 grep 时,它会给出三个结果:
X.hpp
:void do_something(
X.cpp
:void X::do_something(
Y.cpp
:x->do_something(
我还尝试将do_something
的名称更改为一个长期保证唯一的名称,以排除任何名称冲突的可能性。
据我所知,发布的方法定义无疑是被标记为具有内部链接的方法。
【问题讨论】:
如果您非常仔细地检查声明和定义的函数签名,您绝对确定它们没有不同吗?一些“陷阱”是大小写、参数类型和/或限定符、函数限定符、存储类、调用约定,或者只是忘记添加命名空间或类名。 会员是public
吗? class
中的成员默认为 private
。
根据您关于从未修改过这些类的评论,我还会添加另一个“陷阱”。那就是:头卫。您是否认为您可能无意中将标头保护复制粘贴到其他文件中,并且恰好排除了使用正确的类声明?
您是否以某种方式在匿名命名空间中获取了此类?例如,标头保护/命名空间冲突,如 ***.com/a/13536961/166389
@paddy:我添加了一些我认为涵盖了你所有问题的信息(它们都可能与其他方法混淆,对吧?)
【参考方案1】:
这是由于其中一种类型(即foo:Foo
)是模板类型,其中一个模板参数错误地获得了内部链接。
template <typename char const* Name> struct Foo...;
const char constexpr FooBarName[] = "Bar";
using FooBar = Foo<FooBarName>;
FooBar 在任何参数列表中或作为返回类型的存在都会为该方法提供内部链接。甚至 clang-3.8
和 -Weverything
都没有抱怨有一个带有内部链接的模板参数。
明显的解决方法是正确使用extern const char
作为模板字符串参数。
【讨论】:
以上是关于为啥下面的方法会得到内部链接?的主要内容,如果未能解决你的问题,请参考以下文章