为啥下面的方法会得到内部链接?

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 作为模板字符串参数。

【讨论】:

以上是关于为啥下面的方法会得到内部链接?的主要内容,如果未能解决你的问题,请参考以下文章

010 内部链接外部链接路径

为啥我得到一个未定义的回报?

Elementor:浮动到内部内容右侧的元素会影响内容链接 - 如何修复?

为啥我微信里所有链接打开图片都是空白,显示不了?求大神。

内部抽象方法。为啥会有人拥有它们?

如何从模型的方法内部查询主应用程序的小部件