Jo *_*tes 17 c++ ascii utf-8 c++11 c11
为什么在C11或C++ 11中没有UTF-8字符文字,即使有UTF-8字符串文字?我理解,一般来说,字符文字表示单个ASCII字符,它与单个八位字节UTF-8代码点相同,但C和C++都没有说编码必须是ASCII.
基本上,如果我读取标准权限,则无法保证'0'将表示整数0x30,但u8"0"必须表示字符序列0x30 0x00.
编辑:
我知道不是每个UTF-8代码点都适合char.这样的文字只对单八位字节代码点(aka,ASCII)有用,所以我猜这称为"ASCII字符文字"会更合适,所以问题仍然存在.我只是选择用UTF-8构建问题,因为有UTF-8字符串文字.我可以想象可以保证ASCII值的唯一方法就是为每个字符写一个常量,考虑到只有128个,这不会那么糟糕,但仍然......
编写非可移植的C代码是完全可以接受的,这是这样做的很多好理由之一.您可以随意假设您的系统使用ASCII或其某些超集,并警告您的用户不要尝试在EBCDIC系统上运行您的程序.
如果您感觉非常慷慨,可以对支票进行编码.的gperf程序是已知的,以生成代码,其包括这样的检查.
_Static_assert('0' == 48, "must be ASCII-compatible");
Run Code Online (Sandbox Code Playgroud)
或者,对于C11之前的编译器,
extern int must_be_ascii_compatible['0' == 48 ? 1 : -1];
Run Code Online (Sandbox Code Playgroud)
如果您使用的是C11,则可以在字符常量上使用u或U前缀,但不能使用u8前缀...
/* This is useless, doesn't do what you want... */
_Static_assert(0, "this code is broken everywhere");
if (c == '?') ...
/* This works as long as wchar_t is UTF-16 or UTF-32 or UCS-2... */
/* Note: you shouldn't be using wchar_t, though... */
_Static_assert(__STDC_ISO_10646__, "wchar_t must be some form of Unicode");
if (c == L'?') ...
/* This works as long as char16_t is UTF-16 or UCS-2... */
_Static_assert(__STDC_UTF_16__, "char16_t must be UTF-16");
if (c == u'?') ...
/* This works as long as char32_t is UTF-32... */
_Static_assert(__STDC_UTF_32__, "char32_t must be UTF-32");
if (c == U'?') ...
Run Code Online (Sandbox Code Playgroud)
还有那些写在非常便携C和已经被移植到非ASCII系统(一些项目例如).这需要大量的移植工作,除非您知道要在EBCDIC系统上运行代码,否则没有真正的理由去做.
关于标准:编写C标准的人必须与每种可能的C实现相抗衡,包括一些彻头彻尾的奇怪实现.有已知的系统,其中sizeof(char) == sizeof(long),CHAR_BIT != 8,积分类型有陷阱表示,sizeof(void *) != sizeof(int *),sizeof(void *) != sizeof(void (*)()),va_list被堆分配等,这是一场噩梦.
不要试图编写将在您从未听说过的系统上运行的代码,并且不要在C标准中努力寻找保证.
例如,就C标准而言,以下是有效的实现malloc:
void *malloc(void) { return NULL; }
Run Code Online (Sandbox Code Playgroud)
请注意,虽然u8"..."常数保证是UTF-8,u"..."和U"..."有没有保证不同之处在于编码为16比特和每个字符32位,分别与实际的编码必须由执行被记录在案.
摘要:安全地假设2012年的ASCII兼容性.
UTF-8字符文字必须具有可变长度 - 对于其中大多数字符,它不可能存储单个字符,char或者wchar它应该具有什么类型呢?由于我们在C语言和C++中都没有可变长度类型,除了固定大小类型的数组之外,它唯一合理的类型是const char *- 并且C字符串需要以空值终止,因此它不会改变任何东西.
至于编辑:
引用C++ 11标准:
基本源字符集成员的字形旨在识别ISO/IEC 10646子集中对应于ASCII字符集的字符.但是,由于源文件字符到源字符集(在转换阶段1中描述)的映射被指定为实现定义,因此需要实现来记录源文件中基本源字符的表示方式.
(脚注2.3.1).
我认为这是不保证它的充分理由.虽然,正如您在此处的评论中所指出的,对于大多数(或每个)主流编译器,字符文字的ASCII-ness是实现保证的.
对于C++,这已由Evolution工作组问题119解决:添加u8字符文字,其Motivation部分说:
我们有五个编码前缀用于字符串文字(无,L,u8,u,U),但只有四个用于字符文字 - 缺少的是u8.如果窄执行字符集不是ASCII,则u8字符文字将提供一种使用保证ASCII编码来编写字符文字的方法(单代码单元u8编码完全是ASCII).添加对这些文字的支持将添加一个有用的功能,并使语言稍微更一致.
EWG讨论了在Rapperswil中添加u8字符文字并接受改变的想法.本文提供了该扩展的措辞.
使用N4267中的措辞将其纳入工作草案:添加u8字符文字,我们可以在此时找到最新草案标准N4527中的措辞,并注意部分2.14.3说明它们仅限于符合单个UTF-8的代码点代码单位:
以u8开头的字符文字,例如u8'w',是char类型的字符文字,称为UTF-8字符文字.UTF-8字符文字的值等于其ISO10646代码点值,前提是代码点值可用单个UTF-8代码单元表示(即,如果它是US-ASCII字符).包含多个c-chars的UTF-8字符文字格式不正确.
| 归档时间: |
|
| 查看次数: |
4810 次 |
| 最近记录: |