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

Why does the following method get internal linkage?

我正在使用 clang-3.6 并编译一个相当大的项目。在大量 re-factoring 之后,一些 类 中的少数看似随机的方法会导致如下警告:

warning: function 'namespace::X::do_something' has internal linkage but is not defined [-Wundefined-internal]

相同的函数在链接器阶段也显示为缺失。

这是 X.hpp 中这样一个函数定义的匿名 header:

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 的名称更改为保证唯一的长期名称,以排除任何名称冲突的可能性。

据我所知,发布的方法定义无疑是被标记为具有内部链接的方法定义。

这是由于其中一种类型(即 foo:Foo)是模板类型,其中 模板参数之一 错误地获得了内部链接。

template <typename char const* Name> struct Foo{...};

const char constexpr FooBarName[] = "Bar";

using FooBar = Foo<FooBarName>;

FooBar 在任何参数列表中的存在或作为 return 类型的存在将为该方法提供内部链接。甚至 clang-3.8-Weverything 都没有抱怨有一个带有内部链接的模板参数。

明显的解决方法是正确使用 extern const char 作为模板字符串参数。