c++ - gcc 使用专门的定义内联通用模板函数

标签 c++ templates gcc inline compiler-optimization

我怀疑是不是gcc 4.8.3内联了不正确的模板函数...这个问题在debug模式下不会出现,只有在优化模式下才会出现。然而,这发生在复杂的代码库中,我无法在简单的测试用例中重现该问题。

我的代码是这样的

#include "stdio.h"

class A {
 public:

    template<typename T> int WriteNative(const T) { 
      printf("here?\n")
      return 0; 
    }

    template<typename D> 
        void doit() {
        if (WriteNative<double>(1)) {
            printf("A\n");
        } else {
            printf("B\n");
        }
    }

};

// in my real code, this definition is in a different cpp file
template<> int A::WriteNative<double>(const double) { 
  return 1; 
}

int main() {
    A a;
    a.doit<float>();
}

在调试版本中,它打印出 A,而在优化版本中,它打印出 here?\nB

我想任何内联器都使用通用模板函数定义而不是专用模板函数定义。但是 attribute ((noinline)) 没有帮助。

如果我的代码具有已定义的 C++ 行为,有人会问吗?以及如何解决这个问题?

最佳答案

您没有明确说明这一点,但我猜在您的实际代码中您未能在 A 的 .h 文件中声明特化。因此,当 A.h 包含在单独的编译单元中时,编译器并不知道 WriteNative() 的特化。添加特化声明应该可以解决问题,而不必在同一文件中包含定义(即不必内联它):

class A {
    public:
    template<typename T> int WriteNative(const T) { 
      printf("here?\n")
      return 0; 
    }

    template<typename D> 
        void doit() {
        if (WriteNative<double>(1)) {
            printf("A\n");
        } else {
            printf("B\n");
        }
    }
};
template<> int A::WriteNative(const double);

您可以使用三个文件 A.hA.cppmain.cpp 重现您的问题,其中 A. cpp 包含特化的定义,因此当 main.cpp 包含 A.h 时,在优化期间发生内联时以及编译时不知道特化对于 -O0,不会发生内联,因此 WriteNative() 会链接到 A.cpp 中的定义。

编辑: 看这个answer它引用规范来解释为什么这是正确的行为。

14.7.3 [temp.expl.spec]:

6/ If a template, a member template or a member of a class template is explicitly specialized then that specialization shall be declared before the first use of that specialization that would cause an implicit instantiation to take place, in every translation unit in which such a use occurs; no diagnostic is required. If the program does not provide a definition for an explicit specialization and either the specialization is used in a way that would cause an implicit instantiation to take place or the member is a virtual member function, the program is ill-formed, no diagnostic required. An implicit instantiation is never generated for an explicit specialization that is declared but not defined.

关于c++ - gcc 使用专门的定义内联通用模板函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43750053/

相关文章:

c++ - 来自视频文件的简单帧抓取器

c++ - CUDA 中的 64 位 atomicAdd

c++ - 函数模板推导和initlializer_list

有点与 boolean 值的比较

特定于 gcc 4.5 的 C++ 数组创建问题

c++ - 可以在模板化的 typedef 上使用模板特化吗?

c++ - 创建重复声明

c++ - 从 C++11 模板参数包创建空指针

c - 一行 C 程序包含?

c++ - 我如何在 Red Hat 上强制使用 cxx11 ABI?