kem*_*ded 37 c++ sizeof utf-16 language-lawyer
假设程序在具有UTF-16编码字符集的系统上运行.所以根据C++编程语言 - 第4页,第150页:
char可以保存机器字符集的字符.
→我认为char变量的大小是2字节.
但根据ISO/IEC 14882:2014:
sizeof(char),sizeof(signed char)并且sizeof(unsigned char)是1".
或者C++编程语言 - 第4页,第149页:
"[...],所以根据定义,char的大小是1"
→固定尺寸为1.
问题:上述这些语句之间是否存在冲突,或者sizeof(char) = 1只是默认(定义)值,并且实现定义取决于每个系统?
pax*_*blo 35
C++标准(和C,就此而言)有效地定义byte为char类型的大小,而不是 8位数量1.按照C++11 1.7/1(我的大胆):
C++内存模型中的基本存储单元是字节.一个字节至少足以包含基本执行字符集的任何成员和Unicode UTF-8编码形式的八位代码单元,并且由连续的位序列组成,其数量是实现定义的.
因此,表现sizeof(char)为总是 1,不管是什么.
如果你想看看你的基线char变量(可能unsigned变体是最好的)实际上可以保持一个16位的值,你要查看的项目CHAR_BIT来自<climits>.这保存了char变量中的位数.
1许多标准,尤其是与通信协议相关的标准,octet对8位值使用更精确的术语.
Che*_*Alf 28
是的,对于Rôles的C++混淆存在许多严重的冲突和问题char,但这个问题也混淆了一些事情.因此,一个简单的直接回答就是回答"是的","不"或"不知道"问题"你有没有停止殴打你的妻子?".唯一直接的答案是佛教徒"mu",没有问题.
因此,让我们先看看事实.
每比特的数量char由下式定义的执行给定的CHAR_BIT从<limits.h>报头.此数字保证为8或更大.对于C++ 03及更早版本,保证来自C89标准中该符号的规范,C++标准指出(在非规范部分,但仍然)为"合并".对于C++ 11及更高版本,C++标准本身明确地给出了≥8保证.在大多数平台上CHAR_BIT是8,但在一些可能仍然存在的德州仪器数字信号处理器上它是16,并且已经使用了其他值.
无论的价值CHAR_BIT的sizeof(char)定义1,即它不是实现定义:
"
sizeof(char),sizeof(signed char)并且sizeof(unsigned char)是1.
也就是说,char它的变体是存储器寻址的基本单位,这是字节的主要含义,无论是在普通语音中还是在C++中都是正式的:
" C++内存模型中的基本存储单元是字节.
这意味着在前面提到的TI DSP上,没有C++方法可以获得指向各个八位字节(8位部分)的指针.而这反过来意味着需要处理字节序的代码或者其他方式需要将char值视为八位字节序列,特别是对于网络通信,需要使用char在CHAR_BIT8 的系统上没有意义的值来处理事物.它还意味着普通的C++窄字符串文字,如果它们符合标准,并且如果平台的标准软件使用8位字符编码,则会浪费内存.
废物方面是(或是)用Pascal语言直接解决,它区分打包字符串(每个字节多个八位字节)和解包字符串(每个字节一个八位字节),前者用于被动文本存储,后者是用于高效处理.
这说明了单个C++类型中三个方面的基本合并char:
内存寻址单位,又称字节,
最小的基本类型(对于类型来说会很好octet),和
字符编码值单位.
是的,这是一场冲突.
Unicode是一组大量的21位代码点,其中大多数都是自己构成的字符,但其中一些与其他代码点组合形成字符.例如,可以通过组合"e"和"'" - 重音的代码点来形成具有类似"é"的重音的字符.由于这是一种通用机制,因此它意味着Unicode字符可以是任意数量的代码点,尽管它通常只有1.
UTF-16编码最初是基于每个代码点的原始Unicode 16位代码的兼容性方案,当Unicode扩展到每个代码点21位时.基本方案是原始Unicode的定义范围中的代码点表示为它们自己,而每个新的Unicode代码点表示为16位值的代理对.一小部分原始Unicode用于代理对值.
当时,基于每个代码点16位的软件示例包括32位Windows和Java语言.
在具有8位字节的系统上,UTF-16是宽文本编码的示例,即具有比基本可寻址单元宽的编码单元.然后,面向字节的文本编码被称为窄文本.在这样的系统上,C++ char适合后者,但不适合前者.
在C++ 03中,唯一适用于宽文本编码单元的内置类型是wchar_t.
但是,C++标准实际上需要wchar_t适用于代码点,对于现代21位/代码点Unicode来说,它意味着它需要是32位.因此,没有符合UTF-16编码值要求的C++ 03专用类型,每个值16位.由于历史原因,最流行的基于UTF-16的系统作为宽文本编码,即Microsoft Windows,定义wchar_t为16位,在Unicode扩展后与标准公然矛盾,但是,标准是不切实际的这个问题.一些平台定义wchar_t为32位.
C++ 11引入了新的种类char16_t和char32_t,其中前者是(设计成)适于UTF-16编码的值.
关于问题的陈述假设
"具有UTF-16编码字符集的系统
这可能意味着两件事之一:
使用UTF-16作为标准窄编码CHAR_BIT≥16,并且(根据定义)sizeof(char)= 1.我不知道任何系统,即它似乎是假设的.然而,它似乎是当前其他答案中默认的含义.
使用UTF-16作为标准的宽编码,就像在Windows中一样,情况更复杂,因为C++标准不能胜任任务.但是,以Windows为例,一个实际的可能性是sizeof(wchar_t)= 2.而且应该注意到标准与现有的实践和实际考虑因素相冲突,当理想的是标准反而标准化现有的实践,其中有这样的.
现在终于我们能够处理这个问题,
" 上述这些语句之间是否存在冲突,或者
sizeof(char) = 1只是默认(定义)值,并且实现定义取决于每个系统?
这是一种错误的二分法.这两种可能性不是对立的.我们有
在char字符编码单元和存储器寻址单元(字节)之间确实存在冲突.如上所述,Pascal语言具有packed处理该冲突的一个方面的关键字,即存储与处理要求.wchar_t在最广泛使用的采用UTF-16编码的系统(即Windows)中,形式要求与其在UTF-16编码中的使用之间存在进一步的冲突.
sizeof(char) = 1 根据定义:它不依赖于系统.
CHAR_BIT 是实施定义,保证≥8.
不,没有冲突.这两个语句指的是字节的不同定义.
UTF-16意味着字节与八位字节相同- 一组8位.
在C++语言中,字节与之相同char.C++字节可以包含的位数没有限制.C++中的位数 - 字节由CHAR_BIT宏常量定义.
如果您的C++实现决定使用16位来表示每个字符,CHAR_BIT则将为16,每个C++ - 字节将占用两个UTF-16字节.sizeof(char)仍然是1,所有对象的大小将以16位字节为单位进行测量.
char被定义为1个字节.字节是最小的可寻址单元.这在普通系统上是8位,但在某些系统上它是16位,或32位,或其他任何东西(但对于C++必须至少为8).
这有点令人困惑,因为在流行的术语中,字节用于技术上称为八位字节(8位)的字节.
所以,你的第二和第三个引用是正确的.严格来说,第一个引用是不正确的.
由C++标准中的[intro.memory] / 1定义,char只需要能够保存大约100个字符的基本执行字符集(所有字符都出现在0 - 127范围的ASCII中)和八位字节组成UTF-8编码.也许这就是作者对机器字符集的意思.
在硬件是八位字节可寻址但字符集是Unicode的系统上,它很可能char保持8位.但是有些类型char16_t和char32_t(在C++ 11中添加)设计用于代码,而不是char用于具有16位或32位字符集的系统.
因此,如果系统使用,char16_t那么您将使用std::basic_string<char16_t>而不是std::string,等等.
究竟如何处理UTF-16将取决于系统选择的实现细节.Unicode是一个21位字符集,UTF-16是它的多字节编码; 因此系统可以采用类似Windows的路由,并使用std::basic_string<char16_t>UTF-16编码进行字符串处理; 或者它可以std::basic_string<char32_t>用原始的Unicode代码点作为字符.
Alf的帖子详细介绍了可能出现的一些问题.
没有引用标准,很容易给出简单的答案,因为:
字节的定义不是8位.字节是任何大小但可寻址的最小内存单位.最常见的是8位,但没有理由没有16位字节.
C++标准给出了更多限制,因为它必须至少为8位.
因此,无论如何,sizeof(char)始终为1都没有问题.有时它会保持8位,有时是16位,依此类推.