对于C++实现的字符集,什么假设是安全的?

What assumption is safe for a C++ implementation's character set?

本文关键字:假设 安全 什么 C++ 实现 字符集 对于      更新时间:2023-10-16

在C++编程语言6.2.3中,它说:

可以安全地假设实现字符集包括 十进制数字,英语的26个字母字符,以及一些 的基本标点符号。假设是不安全的 那:

  • 8 位字符集中不超过 127 个字符(例如,某些字符集提供 255 个字符)。

  • 没有比英语提供的更多的字母字符(大多数欧洲人 语言提供更多,例如 æ、þ 和 ß)。

  • 字母字符是连续的(EBCDIC在"i"和"j"之间留下了间隙)。

  • 用于写入C++的每个字符都可用(例如, 某些国家/地区字符集不提供 {、}、[、]、|和 \).

  • 字符适合 1 个字节。有嵌入式处理器 没有字节访问 char 为 4 个字节的硬件。另外,一个 可以合理地对基本字符使用 16 位 Unicode 编码。

我不确定我是否理解最后两句话。

在标准的第2.3节中,它说:

基本源字符集由 96 个字符组成:空格 字符,表示水平制表符的控制字符, 垂直制表符、表单进纸和换行符,以及以下 91 图形 字符:

A b c d e f g h i j k l m n o p q r s t u v w x y z
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
0 1 2 3 4 5 6 7 8 9
_ { } [ ] # ( ) <> % : ; . ? * + -/^ & | != , \ " '
...

基本执行字符集和基本执行宽字符集应各自包含基本 源字符集,加上表示警报的控制字符, 退格键和回车符,加上一个空字符(分别是 空宽字符),其表示形式全为零位。

我们可以看到,标准规定像 { } [ ] | \ 这样的字符是基本执行字符集的一部分。 那么为什么 TC++PL 说假设这些字符在实现的字符集中可用是不安全的呢?

对于字符的大小,在标准的第 5.3.3 节中:

sizeof 运算符生成对象中的字节数 表示其操作数。... ...sizeof(char)sizeof(signed char)sizeof(unsigned char)是1。

我们可以看到,标准规定 char 是 1 个字节。 TC++PL在这里想表达的观点是什么?

  • "byte"这个词似乎在第一个引号中使用得很草率。就C++而言,字节始终是字符,但它包含的位数取决于平台(在CHAR_BITS中可用)。有时你想说"一个字节是八位",在这种情况下你会得到不同的含义,这可能是短语"一个字符有四个字节"的预期含义。

  • 执行字符集很可能大于环境提供的输入字符集或
  • 与环境提供的输入字符集不兼容。三元组和备用令牌的存在允许在此类受限平台上表示具有较少输入字符的执行集字符(例如not在所有方面都与!相同,后者并非在所有字符集或键盘布局中都可用)。

过去的情况是,ASCII的一些国家变体,如斯堪的纳维亚语言,使用重音字母字符作为美国ASCII具有标点符号的代码点,如[]{}。 这就是C89包含三元组的原因 - 它们允许在ISO 646的"不变子集"中编写代码。 请参阅维基百科页面上国家变体中使用的字符图表。

例如,斯堪的纳维亚半岛的某个人可能必须阅读:

#include <stdio.h>
int main(int argc, char **argv)
Å
for (int i = 1; i < argc; i++)
printf("%sn", argvÆiØ);
return 0;
ø

而不是:

#include <stdio.h>
int main(int argc, char **argv)
{
for (int i = 1; i < argc; i++)
printf("%sn", argv[i]);
return 0;
}

使用三元组,您可以写:

??=include <stdio.h>
int main(int argc, char **argv)
??<
for (int i = 1; i < argc; i++)
printf("%s??/n", argv??(i??));
return 0;
??>

这在任何语言中都同样可怕。

我不确定这仍然是一个多大的问题,但这就是评论存在的原因。