【发布时间】:2022-02-02 19:46:50
【问题描述】:
在 Windows 上,wchar_t 是一个 UTF-16(LE) 格式的字符,在大多数情况下,它等同于 char16_t。然而,这两种字符类型在 C++ 类型系统中仍然是不同的类型——这让我不确定根据 C++ 标准在这两种字符类型的 sequences 之间进行转换是否合法。
我的问题是:在 C++17 中,执行以下强制转换并读取转换后的指针是否合法:
-
reinterpret_cast<const wchar_t*>(char16_ptr)其中decltype(char16_ptr)是const char16_t*,并且 -
reinterpret_cast<const char16_t*>(wchar_ptr)其中decltype(wchar_ptr)是const wchar_t*
就本问题而言,假设如下:
-
sizeof(wchar_t) == sizeof(char16_t),和 -
wchar_t的格式与char16_t相同(在 Windows 上也是如此)
基本上,这是否违反了严格别名?
我的理解是 cast 本身是有效的,这要归功于 [expr.reinterpret.cast]/7,但是由于类型被不是 char 的东西所别名,因此不能安全地使用转换的结果,unsigned char,或std::byte。这种解释正确吗?
注意:关于wchar_t 和char16_t 的其他问题已被提出,但这个问题不是尽我所能告诉。值得注意的是,问题“Are wchar_t and char16_t the same on Windows?”实际上在指针之间执行了reinterpret_cast,但没有一个答案实际上首先说明了这种转换是否合法。
【问题讨论】:
-
从指向一种类型的指针转换为指向另一种类型的指针是完全合法的。您可能遇到的唯一问题是在 Linux 上编译
wchar_t与char32_t相同,您最终会认为您在字符串结尾之前遇到了空终止符。 -
转换是完全合法的,但这并不意味着使用(即读取、写入)指向的对象是合法的;这可能违反了严格混叠——我认为是这样。问题是这是否违法,或者是否合法。
-
当心! Windows 上的
wchar_t未签名。
标签: c++ c++17 language-lawyer undefined-behavior strict-aliasing