Because the STL grudgingly supports /Zc:wchar_t- (see #212), we occasionally need to detect _NATIVE_WCHAR_T_DEFINED.
For a correct (although weird) example, the STL always defines numeric_limits<wchar_t>:
|
template <>
|
|
class numeric_limits<wchar_t> : public _Num_int_base {
|
Then if wchar_t is a real type, it additionally defines numeric_limits<unsigned short>:
|
#ifdef _NATIVE_WCHAR_T_DEFINED
|
|
// CLASS numeric_limits<unsigned short>
|
|
template <>
|
|
class numeric_limits<unsigned short> : public _Num_int_base {
|
This is backwards, but it works. Users with real wchar_t get both specializations, while users with fake wchar_t get only one.
However, the STL appears to have incorrect logic elsewhere. It follows the numeric_limits pattern for char_traits:
|
// STRUCT char_traits<wchar_t>
|
|
template <>
|
|
struct char_traits<wchar_t> : _WChar_traits<wchar_t> {}; // properties of a string or stream wchar_t element
|
|
|
|
#ifdef _NATIVE_WCHAR_T_DEFINED
|
|
// STRUCT char_traits<unsigned short>
|
|
template <>
|
|
struct char_traits<unsigned short> : _WChar_traits<unsigned short> {
|
|
// properties of a string or stream unsigned short element
|
|
};
|
|
#endif // _NATIVE_WCHAR_T_DEFINED
|
But when wchar_t is a real type, char_traits<unsigned short> doesn't make any sense!
<fstream> has many similar examples. basic_ifstream is always constructible from const wchar_t*:
|
explicit basic_ifstream(
|
|
const wchar_t* _Filename, ios_base::openmode _Mode = ios_base::in, int _Prot = ios_base::_Default_open_prot)
|
And when wchar_t is real, it's also constructible from const unsigned short*:
|
#ifdef _NATIVE_WCHAR_T_DEFINED
|
|
explicit basic_ifstream(const unsigned short* _Filename, ios_base::openmode _Mode = ios_base::in,
|
|
int _Prot = ios_base::_Default_open_prot)
|
I believe that all of our _NATIVE_WCHAR_T_DEFINED logic needs to be audited. When we're separately compiling the STL, wchar_t is always a real type, and we additionally need to provide unsigned short counterparts (so we should detect whether we're building the STL). But when headers are being used to compile user code, users with real wchar_t should see only wchar_t for character-ish things, never unsigned short. (Users with fake wchar_t will see only wchar_t being a typedef for unsigned short, as they should.)
In theory, this should not affect ABI compatibility, although it may affect source compatibility (if users with real wchar_t somehow took a dependency on the unsigned short machinery).
Also tracked by Microsoft-internal VSO-387426 / AB#387426.
Because the STL grudgingly supports
/Zc:wchar_t-(see #212), we occasionally need to detect_NATIVE_WCHAR_T_DEFINED.For a correct (although weird) example, the STL always defines
numeric_limits<wchar_t>:STL/stl/inc/limits
Lines 460 to 461 in 6b0238d
Then if
wchar_tis a real type, it additionally definesnumeric_limits<unsigned short>:STL/stl/inc/limits
Lines 685 to 688 in 6b0238d
This is backwards, but it works. Users with real
wchar_tget both specializations, while users with fakewchar_tget only one.However, the STL appears to have incorrect logic elsewhere. It follows the
numeric_limitspattern forchar_traits:STL/stl/inc/xstring
Lines 265 to 275 in 6b0238d
But when
wchar_tis a real type,char_traits<unsigned short>doesn't make any sense!<fstream>has many similar examples.basic_ifstreamis always constructible fromconst wchar_t*:STL/stl/inc/fstream
Lines 823 to 824 in 6b0238d
And when
wchar_tis real, it's also constructible fromconst unsigned short*:STL/stl/inc/fstream
Lines 850 to 852 in 6b0238d
I believe that all of our
_NATIVE_WCHAR_T_DEFINEDlogic needs to be audited. When we're separately compiling the STL,wchar_tis always a real type, and we additionally need to provideunsigned shortcounterparts (so we should detect whether we're building the STL). But when headers are being used to compile user code, users with realwchar_tshould see onlywchar_tfor character-ish things, neverunsigned short. (Users with fakewchar_twill see onlywchar_tbeing a typedef forunsigned short, as they should.)In theory, this should not affect ABI compatibility, although it may affect source compatibility (if users with real
wchar_tsomehow took a dependency on theunsigned shortmachinery).Also tracked by Microsoft-internal VSO-387426 / AB#387426.