-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
(This will look familiar if you've seen #4962; we should probably fix it similarly to #4963.)
The remove, remove_if, and unique members of forward_list and list use a "tricky" technique to implement the C++20 change that had these functions return a count of the removed elements (WG21-P0646R1). We changed the declared return types from void to auto, and each function ends with e.g.:
#if _HAS_CXX20
return _Removed;
#else
(void) _Removed;
#endifThis approach has the nice property that the functions continue to return void in C++17 mode as they did before the change.
However, the mangled name of the functions is the same in both language modes:
C:\tmp>type meow.cpp
#include <forward_list>
template auto std::forward_list<int>::unique();
C:\tmp>cl /std:c++20 /nologo meow.cpp /c && dumpbin /symbols meow.obj | rg -m1 unique
meow.cpp
043 00000000 SECT1C notype () External | ?unique@?$forward_list@HV?$allocator@H@std@@@std@@QEAA@XZ (public: __cdecl std::forward_list<int,class std::allocator<int> >::unique(void))
C:\tmp>cl /std:c++14 /nologo meow.cpp /c && dumpbin /symbols meow.obj | rg -m1 unique
meow.cpp
03B 00000000 SECT19 notype () External | ?unique@?$forward_list@HV?$allocator@H@std@@@std@@QEAA@XZ (public: __cdecl std::forward_list<int,class std::allocator<int> >::unique(void))
potentially creating an ODR violation when linking C++17 and C++20 TUs that instantiate the same remove/remove_if/unique function template. If a C++20 TU uses the returned value, but the linker chooses the instantiation from a C++17 TU that returns no such value, terrible things will happen.