为什么没有为C ++ 14位分隔符选择空格字符?

时间:2015-01-04 16:38:30

标签: c++ language-lawyer c++14 digit

从C ++ 14开始,感谢n3781(本身不回答这个问题),我们可能会编写如下代码:

const int x = 1'234; // one thousand two hundred and thirty four

目标是改进这样的代码:

const int y = 100000000;

并使其更具可读性。

下划线(_)字符已经由用户定义的文字在C ++ 11中使用,而逗号(,)具有本地化问题 - 许多欧洲国家莫名其妙地†< / sup>使用它作为小数分隔符 - 并且与逗号运算符冲突,尽管我确实想知道通过允许例如允许实际代码被破坏的是什么1,234,567

无论如何,更好的解决方案似乎是空间角色:

const int z = 1 000 000;

这些相邻的数字文字标记可以由预处理器连接,就像字符串文字一样:

const char x[5] = "a" "bc" "d";

相反,我们得到了撇号('),我没有被任何我认识为数字分隔符的书写系统使用。

是否有理由选择撇号而非简单空间?


令人费解的是,因为所有这些语言都在文本中保持了逗号和分散的概念。一个原则上的句子,其句号的作用是&#34;终止&#34;这个句子 - 对我来说,至少,这非常类似于逗号&#34;分开&#34;数字和句号的组成部分&#34;终止&#34;它准备好进行分数输入。

6 个答案:

答案 0 :(得分:34)

之前有一篇论文n3499告诉我们,虽然Bjarne本人建议使用空格作为分隔符:

  

虽然这种方法与一种常见的字体样式一致,但它存在一些兼容性问题。

     
      
  • 它与 pp-number 的语法不匹配,并且最低限度地要求扩展该语法。
  •   
  • 更重要的是,当[a-f]范围内的十六进制数字跟随空格时,会出现一些句法歧义。预处理器不知道是否在空格之后开始执行符号替换。
  •   
  • 它可能会使编辑工具抓住&#34;单词&#34;不太可靠。
  •   

我想以下示例是指出的主要问题:

const int x = 0x123 a;

虽然在我看来这个理由相当薄弱。我仍然无法想出打破它的现实世界的例子。

&#34;编辑工具&#34;理由更糟糕,因为1'234基本上打破了人类已知的每一种语法高亮显示(例如Markdown在上述问题中使用的那些!)并且使得所述荧光笔的更新版本更难以实现。

不过,无论好坏,这都是导致采用撇号的理由。

答案 1 :(得分:16)

不使用空白区域的明显原因是新线路也是如此 白色空间,并且C ++以相同的方式处理所有空白区域。然后关闭 手,我不知道任何接受任意空白的语言 作为分隔符。

据推测,可以使用Unicode 0xA0(非中断空格) - 它是 排版时使用最广泛的解决方案。我看到两个问题 但是:首先,它不在基本字符集中,第二, 它在视觉上并不鲜明;你不能看出它不是一个空间 只是在普通编辑器中查看文本。

除此之外,没有太多选择。你不能使用逗号,因为 这已经是一个合法的令牌(目前还有1,234之类的东西 合法的C ++,含义234)。并且在可能发生的环境中 在法律代码中,例如a[1,234]。虽然我无法想象任何真实的 代码实际上使用这个,有一个基本规则,没有合法的程序, 无论多么荒谬,都应该默默地改变语义。

类似的考虑意味着_也不能使用;如果有的话 #define _234 * 2,然后a[1_234]会默默地改变其含义 代码。

我不能说我对'的选择特别满意,但它 确实有利于在欧洲大陆使用,至少在 某些类型的文本。 (我好像记得曾用德语看过它,因为 例如,虽然在典型的运行文本中,德语和大多数其他文本一样 语言,将使用点或非破坏空间。但也许是的 瑞士德语。)'的问题是解析;序列'1'是 已经合法,'123'。因此1'234之类的内容可能是1, 然后是一个字符常量的开始;我不知道你有多远 必须提前做出决定。没有合法的序列 C ++,其中一个整数常量可以跟一个字符 不变,所以破坏法律代码没有问题,但这意味着 词汇扫描突然变得非常依赖于上下文。

(关于你的评论:选择a时没有逻辑 十进制或千位分隔符。例如,小数分隔符是 当然不是一个句号。它们只是任意约定。)

答案 2 :(得分:10)

wiki开始,我们有一个很好的例子:

auto floating_point_literal = 0.000'015'3;

在这里,我们有.运算符,然后如果要满足另一个运算符,我的眼睛会等待可见的东西,比如逗号或其他东西,而不是空格。

所以撇号在这里比白空做得好得多。

使用空格会是

auto floating_point_literal = 0.000 015 3;

与撇号的情况不同。


本着Albert Renshaw's answer的精神,我认为撇号比轨道中的轻盈种族提出的空间更清晰。

type a = 1'000'000'000'000'000'544'445'555;
type a = 1 000 000 000 000 000 544 445 555;

空间被用于许多事情,比如OP提到的字符串连接,不像撇号,在这种情况下,对于使用分隔数字的人来说,它很清楚。

当代码行变多时,我认为这会提高可读性,但我怀疑这是他们选择它的原因。


关于这些空格,可能值得一看这个C question,其中说:

语言不允许int i = 10 000;(整数文字是一个标记,插入的空格将其分成两个标记)但是通过将初始化程序表示为初始化程序通常很少或没有费用一个表达式,它是文字的计算:

int i = 10 * 1000; /* ten thousand */

答案 3 :(得分:8)

我确实认为没有实际意义:

if (a == 1 1 1 1 1) ...

所以数字可能合并而没有真正的歧义 但十六进制数呢?

0 x 1 a B 2 3

没有办法从拼写错误中消除歧义(通常我们应该看到错误)

答案 4 :(得分:5)

我认为这是因为,在编写代码时,如果到达“线”的末尾(屏幕的宽度),则会发生自动换行(或“自动换行”)。这会导致你的int被分成两半,一半会在第一行,第二行就在第二行......这样一来,word-wrap就会一直保持在一起。

答案 5 :(得分:1)

float floating_point_literal = 0.0000153;   /* C, C++*/

auto floating_point_literal = 0.0000153;    // C++11

auto floating_point_literal = 0.000'015'3;  // C++14

评论并没有伤害:

/*  0. 0000 1530 */ 
float floating_point_literal = 0.00001530; 

二进制字符串可能很难解析:

long bytecode = 0b1111011010011001; /* gcc , clang */  

long bytecode = 0b1111'0110'1001'1001;  //C++14
// 0b 1111 0110 1001 1001  would be better, really.
// It is how humans think.

要考虑的宏:

#define B(W,X,Y,Z)    (0b##W##X##Y##Z)
#define HEX(W,X,Y,Z)  (0x##W##X##Y##Z)
#define OCT(O)        (0##O)



long z = B(1001, 1001, 1020, 1032 ); 

// result :  long z = (0b1001100110201032);

 long h = OCT( 35); 

// result :  long h  = (035); // 35_oct => 29_dec

 long h = HEX( FF, A6, 3B, D0 ); 

// result :  long h  = (0xFFA6BD0);