【问题标题】:g++ 4.2.1: -O breaks linking to a templated functiong++ 4.2.1:-O 中断到模板化函数的链接
【发布时间】:2012-11-20 17:19:54
【问题描述】:

g++ main.c f.c 以下适用于 g++-4.2.1,但
g++ -O3 main.c f.c 会发出警告

/usr/libexec/gcc/powerpc-apple-darwin8/4.2.1/ld: Undefined symbols:
int f<int>(int const*)
collect2: ld returned 1 exit status


// main.c
template <typename T>
int f( const T* A );

int main()
{
    int* A = new int[10];
    int ftemplate = f( A );
}


// f.c
template <typename T>
int f( const T* A )
{   return A[0];
}

int call_f()
{   int* A = new int[10];
    return f( A );  // ok here but not from main()
}

在 macOS 10.4.11 powerpc-apple-darwin8-g++-4.2.1 (GCC) 4.2.1(Apple Inc. build 5564)上, -O2 有效,-O3 无效。
在 macosx 10.7.4 i686-apple-darwin11-llvm-g++-4.2 (来自https://github.com/kennethreitz/osx-gcc-installer),
普通的g++ *.c 有效,g++ -O *.c 给出相同的ld: Undefined symbols 错误。
也许是一个错误 g++ old /usr/bin/ld ?更有可能我做了一些愚蠢的事情......

谁能帮忙,或者看看这是否适用于非 Mac ?谢谢!

【问题讨论】:

  • 一般经验法则:你不使用 -O3.
  • @H2CO3,好的,但这不是问题:在 10.7 上,-O2 也不起作用。为什么要破坏链接器?
  • 它不应该中断。我怀疑这是一个编译器错误。

标签: macos templates linker g++ linker-errors


【解决方案1】:

除非您为函数调用中使用的参数显式实例化函数模板,否则您必须使函数模板定义对它的调用者可见。

这包括 main 中的调用。

它可能适用于未优化的构建,因为编译器会为隐式函数模板实例化发出一个导出的函数定义符号。 C++ 标准允许编译器忽略这样做,而 GCC 在这里为优化构建执行此操作(可能它只是内联调用,然后定义符号变得未使用)。

【讨论】:

  • 谢谢——我的误解,在 SO 上重复了 template-programming-in-c,但令人困惑,因为它有时会起作用。
  • 总是没有错。您可以限制可用的类型并为这些类型显式实例化模板。
  • 你能告诉我更多吗:我怎么说?模板 ? (今天在 g++ 中,而不是 c++11)
  • 你最好将此作为一个新的 stackoverflow 问题提出
猜你喜欢
  • 2013-07-04
  • 1970-01-01
  • 1970-01-01
  • 2014-01-23
  • 2011-05-07
  • 2017-10-20
  • 1970-01-01
  • 1970-01-01
  • 2012-10-23
相关资源
最近更新 更多