【发布时间】:2016-02-06 07:34:06
【问题描述】:
当使用 MSVC(VS 2015)编译时,此程序打印 1 1 而不是 1 2。
f1.cpp:
#include <functional>
static std::function<int ()> helper() {
struct F { int operator()() { return 1; } };
return F();
}
std::function<int ()> f1() { return helper(); }
f2.cpp:
#include <functional>
static std::function<int ()> helper() {
struct F { int operator()() { return 2; } };
return F();
}
std::function<int ()> f2() { return helper(); }
main.cpp:
#include <functional>
#include <iostream>
std::function<int ()> f1();
std::function<int ()> f2();
int main() {
std::cout << f1()() << " " << f2()() << "\n";
}
好像F 的不同定义正在破坏ODR。但是本地类不应该是不同的吗?有趣的是,如果我们将 F 替换为 lambda 函数,则不会发生冲突。
那么这是编译器错误还是我误解了单一定义规则?
【问题讨论】:
-
MSVC 遇到这样的错误有点疯狂。如果您删除
static并使用未命名的命名空间,它甚至会出错。 -
当你使用两个独立的 cout 而不是一个时会发生什么?
-
你确定吗?在 MSVC 14.0 中,如果将
helper()放在匿名命名空间中,那么冲突就会消失。 -
我想知道这是否是由于COMDAT folding 攻击你可以使用/opt:noicf 关闭它
-
获得与
/link /opt:noicf相同的行为。我假设折叠只适用于具有相同定义的函数,这里不是这种情况。
标签: c++ visual-c++ one-definition-rule