On 2014-09-23 21:18, Öö Tiib wrote:> On Tuesday, 23 September 2014
10:23:11 UTC+3, markus wrote:
>> On Windows wchar_t, char16_t and unsigned short/uint16_t all use
>> the same underlying type uint16_t. According the C++11 standard
>> they are all distinct types.
>
> "Windows" is series of operating systems. It does not deal with C++
> fundamental types and typedefs.
The Win32/64 API defines wchar_t as UTF-16 and unsigned short as 16-bit int.
> Did you mean some particular version of some particular C++ compiler
> targeting some particular version of Windows?
All of them on Win32/64. AFAIK, everything tries to be compatible to
either Visual C++ or GCC/Mingw and they do what I mentioned.
>> Looking at the Firefox source, they are (reinterpret)casting
>> between char/char16_t/wchar_t.
>>
>> Looking at the Qt source, depending on the platform they are
>> happily casting between uint16_t/wchar_t or uint32_t/wchar_t.
>>
>> From what I can tell, this does violate the aliasing rules. Am I
>> missing something? Do GCC/Visual C++ make some special guarantees
>> that this will work?
>
> Casting between different unsigned integral types is one of few
> things that is quite fully well defined in C++ standard. Did you mean
> that non-'char' pointers are somewhere taken and type-punned and then
> used in mix in Qt and Firefox source code?
Yes, I'm taking about pointers. E.g. Firefox has a helper for automagic
casting (Char16.h):
class char16ptr_t
{
private:
const char16_t* mPtr;
public:
char16ptr_t(const char16_t* aPtr) : mPtr(aPtr) {}
char16ptr_t(const wchar_t* aPtr) :
mPtr(reinterpret_cast<const char16_t*>(aPtr))
{}
operator const char16_t*() const
{
return mPtr;
}
operator const wchar_t*() const
{
return reinterpret_cast<const wchar_t*>(mPtr);
}
operator std::wstring() const
{
return std::wstring(static_cast<const wchar_t*>(*this));
}
/* Explicit cast operators to allow things like (char16_t*)str. */
explicit operator char16_t*() const
{
return const_cast<char16_t*>(mPtr);
}
explicit operator wchar_t*() const
{
return const_cast<wchar_t*>(static_cast<const wchar_t*>(*this));
}
explicit operator const char*() const
{
return reinterpret_cast<const char*>(mPtr);
}
explicit operator const unsigned char*() const
{
return reinterpret_cast<const unsigned char*>(mPtr);
}
explicit operator unsigned char*() const
{
return const_cast<unsigned char*>(reinterpret_cast<const unsigned
char*>(mPtr));
}