来自c ++ 2003 2.13
宽字符串文字的类型为“ n const wchar_t 的数组”并且具有静态存储持续时间,其中n是下面定义的字符串的大小
宽字符串文字的大小是转义序列,通用字符名称和其他字符的总数,加上一个用于终止L'\ 0'。
来自c ++ 0x 2.14.5
宽字符串文字的类型为“数组n const wchar_t ”,其中n是字符串的大小,如下所示
char32_t或宽字符串文字的大小是转义序列,通用字符名称和其他字符的总数,加上一个用于终止U'\ 0'或L'\ 0'。
char16_t字符串文字的大小是转义序列,通用字符名称和其他字符的总数,加上需要代理项对的每个字符一个,加上一个用于终止u'\ 0'。 / p>
C ++ 2003中的陈述非常模糊。但是在C ++ 0x中,当计算字符串的长度时,宽字符串文字wchar_t应被视为与char32_t相同,并且与char16_t不同。
有一篇文章明确说明了Windows如何在https://stackoverflow.com/questions/402283?tab=votes%23tab-top
中实现wchar_t简而言之,Windows中的wchar_t是16位并使用UTF-16编码。标准中的陈述显然在Windows中留下了一些冲突。
例如,
wchar_t kk[] = L"\U000E0005";
这超过16位,对于UTF-16,它需要两个16位来编码它(代理对)。
但是,从标准来看,kk是2 wchar_t的数组(通用名称\ U000E005为1,\ 0为1)。
但是在内部存储中,Windows需要3个16位wchar_t对象来存储它,2个wchar_t用于代理对,1个wchar_t用于\ 0。因此,从数组的定义来看,kk是一个3 wchar_t的数组。
这显然是相互冲突的。
我认为Windows的一个最简单的解决方案是“禁止”在wchar_t中需要代理对的任何内容(“禁止”在BMP之外的任何unicode)。
我的理解有什么不对吗?
感谢。
答案 0 :(得分:4)
该标准要求wchar_t
足够大以容纳支持的字符集中的任何字符。基于此,我认为你的前提是正确的 - VC ++使用两个\U000E0005
单位表示单个字符wchar_t
是错误的。
BMP之外的字符很少使用,Windows本身在内部使用UTF-16编码,因此VC ++以这种方式运行简单方便(即使不正确)。但是,而不是"禁止"这些字符,wchar_t
的大小可能会在将来增加而char16_t
在Windows API中占据一席之地。
你所链接的答案也有些误导:
在Linux上,
wchar_t
是4字节,而在Windows上,它是2字节
wchar_t
的大小完全取决于编译器,与操作系统无关。恰好VC ++使用2个字节用于wchar_t
,但是再一次,这可能会在未来发生很大变化。
答案 1 :(得分:2)
Windows对wchar_t一无所知,因为wchar_t是一个编程概念。相反,wchar_t只是存储,它对你存储在其中的数据的语义值一无所知(也就是说,它对Unicode或ASCII或其他什么都不了解。)
如果针对Windows的编译器或SDK将wchar_t定义为16位,则该编译器可能与C ++ 0x标准冲突。 (我不知道是否有一些允许wchar_t为16位的get-out子句。)但无论如何编译器可以将wchar_t定义为32位(符合标准)并提供运行时函数当您需要将wchar_t *传递给Windows API时,转换为UTF-16或从UTF-16转换。