Skip to content

Potential ODR violation linking C++14 with C++17+ TUs that use container emplace functions #4962

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();
#endif

This 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfixedSomething works now, yay!

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions