我发现了一个示例,其中输出根据优化设置(-O3 与 none)而有所不同,但 GCC 4.8.2 即使使用 -std=c++11 -Wall -pedantic 选项也不会产生警告。

在这种特殊情况下,我假设“忘记” header.h 中的注释行是一个错误,并且使用 -O3c<int>::get() 被内联。

但是,有什么方法可以保护自己免受此类错误的影响——也许是编译器或链接器选项?

标题.h:

#ifndef HEADER_H
#define HEADER_H

template<class T>
struct c
{
   int get() { return 0; }
};

// template<> int c<int>::get();

#endif

影响.cpp:
#include "header.h"

template<>
int c<int>::get()
{
   return 1;
}

主.cpp:
#include <iostream>
#include "header.h"

int main()
{
    c<int> i;
    std::cout << i.get() << '\n'; // prints 0 with -O3, and 1 without
}

build :
c++ -std=c++11 -pedantic -Wall -O3 -c imp.cpp
c++ -std=c++11 -pedantic -Wall -O3 -c main.cpp
c++ -std=c++11 -pedantic -Wall -O3 imp.o main.o

最佳答案

  • 如果你的头文件中有一行,你得到的是该成员函数的显式特化声明。

    因此, main.cpp 确保在其他一些编译单元中定义,并且一切正常。
  • 如果你把它去掉,你就违反了 ODR:

    类模板的特定实例化在编译单元中是不同的。导致“格式错误,不需要诊断”,所以一切都好。

    并且(目前?)没有编译器选项来强制 gcc 诊断它。
  • 关于c++ - 不同的行为取决于优化选项,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28356840/

    10-11 22:00
    查看更多