【问题标题】:c++ is a white space independent language, exception to the rulec++ 是一种独立于空格的语言,规则的例外
【发布时间】:2012-09-06 04:58:59
【问题描述】:

This wikepedia page 将 c++ 定义为“空白独立语言”。虽然与所有语言一样大部分都是正确的,但该规则也有例外。目前我能想到的只有这样一个:

vector<vector<double> >

必须有空格,否则编译器会将 >> 解释为流运算符。周围还有什么。编译一个例外列表会很有趣。

【问题讨论】:

  • 您不必担心使用 C++11 的那个。
  • C++11 专门添加了一条规则,允许vector&lt;vector&lt;double&gt;&gt;
  • 请参阅g++ 4.7 evaluates operator “” as sibling to macro expansion,了解 C++11 用户定义文字的问题,您需要在其中添加空格。
  • @Mat: 非常真实......在 C++11 中你有很多更严重的事情要担心,即使它仍然存在,这个问题也真的无关紧要:-)
  • 完全限定模板参数时需要一个空格:::std::vector&lt; ::std::string&gt; vec;

标签: c++ whitespace


【解决方案1】:

按照这个逻辑,您可以使用任何两个字符的词位来产生这样的规则“例外”。例如,+=+ = 的解释会有所不同。不过,我不会称它们为例外。在许多情况下,在 C++ 中,“根本没有空格”与“一个或多个空格”完全不同。当有人说 C++ 与空间无关时,他们通常是指 C++ 中的“一个空格”通常与“多个空格”相同。

这反映在语言规范中,该规范规定(参见 2.1/1)在翻译的第 3 阶段允许实现用一个空格字符替换多个空白字符序列。

【讨论】:

    【解决方案2】:

    解析 C++ 的语法和语义规则确实相当复杂(我努力表现得很好,我认为有人有权说“一团糟”)。这一事实的证明是,多年来不同的编译器作者只是争论什么是合法的 C++,什么不是。

    例如,在 C++ 中,您可能需要先解析无限数量的标记,然后再决定第一个标记的语义是什么(可怕的 "most vexing parse rule",它也经常咬新人)。

    但是,您的反对 IMO 并没有真正的意义……例如,+++ + 的含义不同,而在 Pascal 中,beginbeg in 不同。这是否使 Pascal 成为一种空间依赖语言?有没有与空间无关的语言(brainf*ck 除外)?

    关于 C++03 &gt;&gt;/&gt; &gt; 的唯一问题是打字时这个错误非常常见,因此他们决定在语言定义中增加更多复杂性来解决 C++11 中的这个问题。

    一个空格而不是更多空格可以产生影响的情况(这种情况可以区分依赖空间的语言,但在&gt; &gt; / &gt;&gt; 情况下不起作用)确实很少:

    1. 在双引号字符串中(但每个人都希望这样,而且我知道的每种支持字符串文字的语言都这样做)

    2. 在单引号内(相同,即使没有多少 C++ 程序员知道单引号内可以有多个字符)

    3. 在预处理器指令中,因为它们以行为基础工作(换行符是一个空格,它在那里会有所不同)

    4. stefanv 注意到的行继续:要继续单行,您可以在换行符之前放一个反斜杠,在这种情况下,语言将忽略这两个字符(即使在标识符中间也可以这样做,即使典型用途只是使长预处理器宏可读)。如果您在反斜杠之后和换行符之前放置其他空白字符,则无法识别行继续(一些编译器无论如何都会接受它并简单地检查一行的最后一个非空白是否是反斜杠)。也可以使用与反斜杠等效的三元组 ??/ 指定行继续(任何合理的编译器都应在 IMO 找到三元组时发出警告,因为它们很可能没有被程序员缩进)。

    5. 在单行 cmets // 内,因为在评论中间向其他空格添加换行符也会产生影响

    【讨论】:

    • 我并不是真的反对,我认为这只是一个有趣的问题。 >> 和 >> 不是您认为与空间无关的东西,我想我想知道还有多少其他这样的例子。
    • @Ben:什么例子?一个有效的令牌也是一个有效的较长令牌的前缀吗?你有&lt; &lt;&lt;+= + =&lt;=&lt; =&gt;= &gt; =和更多。关于 C++ 中令程序员惊讶的语法级问题,还有三元组、andor 和其他关键字,这些关键字显然只是为了好玩而定义的。关于语义上的惊喜,像 std::string s; s=3.14; 这样的东西是完全有效的 C++,或者像 false["foo"] 这样的东西也是有效的 C++。有问题的零件清单真是无穷无尽……
    • 您应该将其添加到您的答案中,即。这就是我感兴趣的事情。
    • @Ben:你应该小心暴露 C++ 问题。由于我不理解的原因,许多 C++ 程序员(尤其是如果他们不久前刚接触 C++ 的话)对这门语言过于狂热,并且说任何对语言的任何部分都不够赞扬的话只会引发反对票。相反,您可以为废话投票,例如使用模板元编程来构建二进制文字的半生不熟和破碎的实现(我很乐意对此开玩笑,但我不是......见stackoverflow.com/a/2611850/320726
    • 感谢您的建议,这个问题真的只是我的兴趣。如果人们只为投票提问,我不相信堆栈交换系统会起作用。如果人们认为我的问题措辞不当或离题,那么他们可以投反对票。但就目前而言,我认为我的评论提出了一些有趣的问题,并且显然激发了很多思考,我相信这是提出一个好问题的基础。
    【解决方案3】:

    不管你喜不喜欢,但宏也是 C++ 的一部分,多行宏应该用反斜杠隔开,后跟 EOL,反斜杠和 EOL 之间不能有空格。 不是什么大问题,但仍然是空白例外。

    【讨论】:

    • backslash+newline 对与宏无关,只是行延续序列。您甚至可以在标识符或字符串文字的中间使用它。没有多行宏,它们位于使用续行符分割的单行上。
    • @6502:在技术上你是正确的,对我来说,宏是我需要续行的唯一地方,使它们看起来多行,因此我的回答。但你的评论是一个有效的解释。
    • +1:如果问题是关于一个空格而不是更多空格在哪里产生影响,那么行继续在形式上是一个有意义的案例(但这仍然不会使 IMO 成为依赖于空间的语言从实际的角度来看,因为续行真的很接近某种“前语言”部分)
    【解决方案4】:

    这是因为解析器在 c++11 之前的限制,现在不再是这种情况。

    原因在于,与运算符 >>

    相比,难以将 >> 解析为模板的结尾

    【讨论】:

      【解决方案5】:

      虽然 C++03 确实 在所有情况下都将 &gt;&gt; 解释为移位运算符(在流中使用时已被覆盖,但它仍然是移位运算符),但 C+ 中的语言解析器+11 现在将在合理的情况下尝试关闭大括号。

      【讨论】:

        【解决方案6】:
        • 嵌套模板参数:set&lt;set&lt;int&gt; &gt;
        • 字符字面量:' '
        • 字符串字面量:" "
        • 关键字和标识符的对位:else return x;void foo(){}

        【讨论】:

          猜你喜欢
          • 2010-09-07
          • 1970-01-01
          • 2012-12-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多