- 
                Notifications
    
You must be signed in to change notification settings  - Fork 1.6k
 
Description
The emplace_front and emplace_back members of our containers and emplace members of our container adaptors use a "tricky" technique to implement the C++17 change that had these functions return a reference to the newly emplaced element. We changed the declared return types from void to decltype(auto), and each function returns with e.g.:
#if _HAS_CXX17
    return back();
#endifThis approach has the nice property that the functions continue to return void in C++14 mode as they did before the change.
However, the mangled name of the functions is the same in both language modes (credit to STL):
C:\Temp>type meow.cpp
#include <vector>
decltype(auto) meow(std::vector<int>& v) {
    return v.emplace_back(1729);
}
C:\Temp>cl /EHsc /nologo /W4 /std:c++14 /c meow.cpp
meow.cpp
C:\Temp>dumpbin /symbols meow.obj | rg emplace_back
0AC 00000000 SECT19 notype ()    External     | ??$emplace_back@H@?$vector@HV?$allocator@H@std@@@std@@QEAA?A_T$$QEAH@Z (public: decltype(auto) __cdecl std::vector<int,class std::allocator<int> >::emplace_back<int>(int &&))
196 00000000 SECT73 notype       Static       | $unwind$??$emplace_back@H@?$vector@HV?$allocator@H@std@@@std@@QEAA?A_T$$QEAH@Z
199 00000000 SECT74 notype       Static       | $pdata$??$emplace_back@H@?$vector@HV?$allocator@H@std@@@std@@QEAA?A_T$$QEAH@Z
C:\Temp>cl /EHsc /nologo /W4 /std:c++latest /c meow.cpp
meow.cpp
C:\Temp>dumpbin /symbols meow.obj | rg emplace_back
0B0 00000000 SECT1A notype ()    External     | ??$emplace_back@H@?$vector@HV?$allocator@H@std@@@std@@QEAA?A_T$$QEAH@Z (public: decltype(auto) __cdecl std::vector<int,class std::allocator<int> >::emplace_back<int>(int &&))
19C 00000000 SECT74 notype       Static       | $unwind$??$emplace_back@H@?$vector@HV?$allocator@H@std@@@std@@QEAA?A_T$$QEAH@Z
19F 00000000 SECT75 notype       Static       | $pdata$??$emplace_back@H@?$vector@HV?$allocator@H@std@@@std@@QEAA?A_T$$QEAH@Z
potentially creating an ODR violation when linking C++14 and C++17 TUs that instantiate the same emplace function. If a C++17 TU uses the returned reference, but the linker chooses the instantiation from a C++14 TU that returns no such reference, terrible things will happen.