std::size_t CountNonzeroUnsignedShorts(const unsigned short *p)
{
return std::wcslen(reinterpret_cast<const wchar_t *>(p));
}
wchar_t *wmemset(wchar_t *dest, wchar_t c, size_t count
{
__stosw(reinterpret_cast<unsigned short *>(dest), c, count);
return dest;
}
10.4 a type that is the signed or unsigned type corresponding to the dynamic type of the object;
If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined:
Is pointer aliasing legal between wchar_t, char16_t, char32_t and their underlying types? In other words, is this legal on a platform for which char16_t and wchar_t have an underlying type of "unsigned short", as in Windows?
std::size_t CountNonzeroUnsignedShorts(const unsigned short *p)
{
return std::wcslen(reinterpret_cast<const wchar_t *>(p));
}
Or its inverse case:
wchar_t *wmemset(wchar_t *dest, wchar_t c, size_t count
{
__stosw(reinterpret_cast<unsigned short *>(dest), c, count);
return dest;
}
I'm wondering because of the seemingly ambiguous wording in the Standard:10.4 a type that is the signed or unsigned type corresponding to the dynamic type of the object;
Is unsigned short an "unsigned type corresponding" to wchar_t (on platforms such as Windows NT, Nintendo 3DS, etc.)?
If wchar_t is not allowed to alias its underlying type, then perhaps it should be mentioned in [diff.wchar.t] that this aliasing incompatibility is another one of the differences from C.
Although unrelated, I'm wondering about this wording:If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined:
What is meant by "access the stored value"--particularly, does it include writing in addition to reading? When you write to a glvalue, you don't access the stored *value* at all, because you're replacing it. This seems ambiguous to me.
在 2016年12月2日星期五 UTC+8上午3:41:59,Nicol Bolas写道:On Thursday, December 1, 2016 at 2:33:55 PM UTC-5, Myriachan wrote:Is pointer aliasing legal between wchar_t, char16_t, char32_t and their underlying types? In other words, is this legal on a platform for which char16_t and wchar_t have an underlying type of "unsigned short", as in Windows?
std::size_t CountNonzeroUnsignedShorts(const unsigned short *p)
{
return std::wcslen(reinterpret_cast<const wchar_t *>(p));
}
Or its inverse case:
wchar_t *wmemset(wchar_t *dest, wchar_t c, size_t count
{
__stosw(reinterpret_cast<unsigned short *>(dest), c, count);
return dest;
}
I'm wondering because of the seemingly ambiguous wording in the Standard:10.4 a type that is the signed or unsigned type corresponding to the dynamic type of the object;
Is unsigned short an "unsigned type corresponding" to wchar_t (on platforms such as Windows NT, Nintendo 3DS, etc.)?
If wchar_t is not allowed to alias its underlying type, then perhaps it should be mentioned in [diff.wchar.t] that this aliasing incompatibility is another one of the differences from C.
[basic.lval]/8 is the principle location that deals with whether aliasing is allowed. And it says nothing about the "underlying type" for any type.
So you can't even perform aliasing between `int` and `enum Name:int`, let alone between the underlying types of the character types. So there's no reason to mention it there.Although unrelated, I'm wondering about this wording:If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined:
What is meant by "access the stored value"--particularly, does it include writing in addition to reading? When you write to a glvalue, you don't access the stored *value* at all, because you're replacing it. This seems ambiguous to me.
From [defns.access]: "to read or modify the value of an object"
Totally agreed.
However, there may be more problems about interopability.
How do these literally identical types (like `wchar_t`) mapped from C to C++?
On Sunday, December 4, 2016 at 1:10:51 PM UTC-5, FrankHB1989 wrote:在 2016年12月2日星期五 UTC+8上午3:41:59,Nicol Bolas写道:On Thursday, December 1, 2016 at 2:33:55 PM UTC-5, Myriachan wrote:Is pointer aliasing legal between wchar_t, char16_t, char32_t and their underlying types? In other words, is this legal on a platform for which char16_t and wchar_t have an underlying type of "unsigned short", as in Windows?
std::size_t CountNonzeroUnsignedShorts(const unsigned short *p)
{
return std::wcslen(reinterpret_cast<const wchar_t *>(p));
}
Or its inverse case:
wchar_t *wmemset(wchar_t *dest, wchar_t c, size_t count
{
__stosw(reinterpret_cast<unsigned short *>(dest), c, count);
return dest;
}
I'm wondering because of the seemingly ambiguous wording in the Standard:10.4 a type that is the signed or unsigned type corresponding to the dynamic type of the object;
Is unsigned short an "unsigned type corresponding" to wchar_t (on platforms such as Windows NT, Nintendo 3DS, etc.)?
If wchar_t is not allowed to alias its underlying type, then perhaps it should be mentioned in [diff.wchar.t] that this aliasing incompatibility is another one of the differences from C.
[basic.lval]/8 is the principle location that deals with whether aliasing is allowed. And it says nothing about the "underlying type" for any type.
So you can't even perform aliasing between `int` and `enum Name:int`, let alone between the underlying types of the character types. So there's no reason to mention it there.Although unrelated, I'm wondering about this wording:If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined:
What is meant by "access the stored value"--particularly, does it include writing in addition to reading? When you write to a glvalue, you don't access the stored *value* at all, because you're replacing it. This seems ambiguous to me.
From [defns.access]: "to read or modify the value of an object"
Totally agreed.
However, there may be more problems about interopability.
How do these literally identical types (like `wchar_t`) mapped from C to C++?
Is that a question C++ is supposed to answer?
Interop is generally implementation-defined territory; indeed, the C++ object model doesn't even match up with the C object model.
In C, you can malloc some memory, cast the pointer, and you suddenly have a valid object of the cast type.
That doesn't work in C++; [intro.object]/1 does not permit malloc alone to create an object. You can only create a C++ object via a declaration, temporary, new expression, or union-manipulation.
So how "identical" these things are depends on your implementation. As it always has.
#ifdef __cplusplus
#include <cwchar>
#else
#include <wchar.h>
#endif
unsigned Meow(int *a, wchar_t *b)
{
*a = 5;
*b = 10;
return *a;
}