This program prints 1 1
instead of 1 2
when compiled with MSVC (up to VS 2015).
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";
}
It's as if the different definitions of F
are breaking ODR. But shouldn't local classes be distinct? Interestingly, if we replace F
with lambda functions there is no conflict.
So is this a compiler bug or am I misunderstanding the one definition rule?
It's clearly a bug in MSVC, as all the types are unique. Perhaps for structs defined inside some function (in this case helper
) MSVC internally treats them as if they are defined as helper::F
while if helper is static it should have done something like this f1_cpp::helper::F
instead.
As a result at link time linker sees two identically named inline functions and merges them into one.
Most likely by reordering input files you can get 2 2
if you weren't happy with 1 1
:)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With