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

Lig*_*ica 63 c++ language-lawyer digit c++14

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

const int x = 1'234; // one thousand two hundred and thirty four
Run Code Online (Sandbox Code Playgroud)

目的是改进这样的代码:

const int y = 100000000;
Run Code Online (Sandbox Code Playgroud)

并使其更具可读性.

下划线(_)字符已经由用户定义的文本采取了C++ 11,和逗号(,)的本地化问题-许多欧洲国家令人困惑以此作为小数点分隔符-与逗号运算符的冲突,虽然我做的想知道什么样的现实世界的代码可能会被允许,例如1,234,567.

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

const int z = 1 000 000;
Run Code Online (Sandbox Code Playgroud)

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

const char x[5] = "a" "bc" "d";
Run Code Online (Sandbox Code Playgroud)

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

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


令人费解,因为所有这些语言都在文本中保留了一个逗号"分开"一个原本句子的概念,其句号用于"终止"句子 - 至少对我来说,这非常类似于逗号"分开"一个数字的整数部分和一个句号"终止"它为分数输入做好准备.

Lig*_*ica 35

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

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

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

我想下面的例子是注意到的主要问题:

const int x = 0x123 a;
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • `#define abc + 1`,`const int x = 0x123 abc;` (14认同)
  • @LightnessRacesinOrbit我不确定它是否那么简单.为了允许宏替换你必须解析`abc`作为*标识符*,但是你必须指定某种*pp-number*和*identifier*的串联,这是......怪异的.此外,显然还有[打破Objective-C的重大问题](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3499.html#Spacing). (8认同)
  • @aschepler:如果我是地球总统,那么"文字"会在其制作中包含一个空格,使得"0x123 a45"成为单一的,尽管是多重标记的文字.你能想到一个场景,其中"a45"被解释为整数文字的一部分吗?它之前没有操作员或任何东西,那么还有什么呢? (4认同)
  • @TC宏在第4阶段进行了扩展,字符串文字在第6阶段连接.我希望"数字文字连接"也可以在第6阶段进行,从而保持示例代码的行为而不会破坏任何内容. (2认同)

Jam*_*nze 16

不使用空格的显而易见的原因是新行也是空格,并且C++以相同的方式处理所有空格.另外,我不知道任何接受任意空格作为分隔符的语言.

据推测,可以使用Unicode 0xA0(非中断空间) - 它是排版时使用最广泛的解决方案.然而,我看到了两个问题:第一,它不在基本字符集中,第二,它在视觉上并不鲜明; 通过查看普通编辑器中的文本,您无法看到它不是空间.

除此之外,没有太多选择.你不能使用逗号,因为它已经是一个合法的令牌(类似于1,234目前合法的C++,含义234).并且在可能出现在法律代码中的情况下,例如a[1,234].虽然我无法想象任何实际使用此代码的真实代码,但有一条基本规则是,任何法律程序,无论多么荒谬,都应该默默地改变语义.

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

我不能说我对选择感到特别满意',但它确实具有在欧洲大陆使用的优势,至少在某些类型的文本中使用.(我似乎记得曾用德语看过它,例如,虽然在典型的运行文本中,德语和大多数其他语言一样,会使用点或非突破空间.但也许它是瑞士德语.)问题'在于解析; 序列'1'已经合法了'123'.所以类似的东西1'234可能是一个1,然后是一个字符常量的开始; 我不确定你要做多远才能做出决定.没有合法的C++序列,其中一个整数常量可以跟一个字符常量,所以打破合法代码没有问题,但这意味着词汇扫描突然变得非常依赖于上下文.

(关于你的评论:在选择小数或千位分隔符时没有逻辑.例如,小数分隔符肯定不是句号.它们只是任意约定.)

  • @LightnessRacesinOrbit甚至`void f(int); void f(int,int); F(12345);` (15认同)
  • @ G.Samaras:C将"空白"定义为"......空格,水平制表符,换行符,垂直制表符和换页符",这完全是传统的. (2认同)

gsa*_*ras 10

维基,我们有一个很好的例子:

auto floating_point_literal = 0.000'015'3;
Run Code Online (Sandbox Code Playgroud)

在这里,我们有.操作员,然后如果要满足另一个操作员,我的眼睛会等待可见的东西,如逗号或其他东西,而不是空白.

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

有了空白就可以了

auto floating_point_literal = 0.000 015 3;
Run Code Online (Sandbox Code Playgroud)

这与撇号的情况不一样.


按照阿尔伯特·伦肖的回答,我认为撇号比"轨道中的轻盈种族"提出的空间更清晰.

type a = 1'000'000'000'000'000'544'445'555;
type a = 1 000 000 000 000 000 544 445 555;
Run Code Online (Sandbox Code Playgroud)

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

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


关于这些空间,可能值得一看这个C 问题,它说:

该语言不允许int i = 10 000;(整数文字是一个标记,插入的空格将其分成两个标记)但是通常将初始化程序表达为一个计算文字的表达式,几乎不会产生任何费用:

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

  • 它的现代性不是问题.仔细研究一下.如果日期在您所在的地区没有重大意义,请谷歌. (10认同)
  • 我认为,你知道那篇关于空白超载的出版日期(特别是月份和日期,而不是年份),对吧? (3认同)

hli*_*ide 9

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

if (a == 1 1 1 1 1) ...
Run Code Online (Sandbox Code Playgroud)

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

0 x 1 a B 2 3
Run Code Online (Sandbox Code Playgroud)

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


Alb*_*haw 5

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

  • 我不认为这是_the_理由,但这是一个我没有考虑过的有趣的原因.在更多人的答案中向更多的想法开放:) (4认同)
  • 我不是在C++设计委员会,但从我收集的问题来看,这些问题通常不会影响决策. (3认同)