繁体   English   中英

为什么函数中的花括号在 C 风格的语言中不是可选的?

[英]Why are curly braces in functions not optional in C-style languages?

语言设计者选择在以下场景中使用大括号可选:

if (a)
    b
while (a)
    b
...

为什么在函数中不允许相同,像这样?

int add(int a, int b)
    return a + b;

我敢肯定这会搞乱语法。 例如,这个空函数定义之间没有区别......

void empty()
{
    ;
}

...还有这个函数声明:

void empty();

我不确定他们确实“选择”了这个。 相反,省略花括号 for if、while、for 等的能力是它们指定语法的方式的自然结果。 语法禁止它用于函数可能是因为旧式的函数声明。

没有与函数定义相关的固定关键字。 对于if / else / for / while / switch有一个这样的关键字标志着逻辑控制结构的开始。

尽管上下文允许我们人类辨别int some_name (some_expression) some_other_expressions; 是一个函数 - 在编程实践中(尽管明确可行)需要大量回溯以确保标记流中前面的 3-4-6 个符号没有将其从函数声明更改为其他内容。

一个编程语言解析器可以根据它的解析方法进行分类,要么获取标记列表中的当前标记并检查下一个标记是否确认“这是一个 if”或“这是一个函数”,或者它需要一个最大的查找-提前标记(2-3-6?)并确认“这可能是一个函数”,“现在我看到第 5 个标记,这肯定是一个函数”,或者它使用回溯和可变前瞻方法,走得更远在令牌列表中根据需要确保我们正在研究的构造不是别的东西。

如果我要推测,我会说这是因为一个函数通常包含多个语句,而 if 或 while 语句通常只包含一个语句。 此外,事实证明它是有远见的,因为在 C++ 中允许省略 {} 会导致成员函数中的歧义。 例如:

struct s
{
     void f() const int i; //does const refer to int i or the function?
}

花括号不是“if”和“if-else”控制语句的可选组件。 “if”控制语句的语法产生式允许一个非终结符跟在表达式之后。 “if-else”控制语句的语法产生式允许一个非终结符跟在表达式之后,一个非终结符跟在“else”终结符之后。 该非终结符的名称是 <statement>。

在控制结构(又名控制语句)的上下文中,大括号属于称为 <compound-statement>(有时称为 <block>)的语言非终结符。 非终结符 <compound-statement> 出现在 <statement> 语法产生式的右侧,这就是为什么花括号可以与“if”和“if-else”控制语句一起使用的原因(即,复合语句是一个语句)。

<statement> ::= <if-then-statement> | 
                <if-then-else-statement> | 
                <for-statement> |
                <do-while-statement> |
                ...
                <compound-statement>

<statement-list> ::=  <statement> | <statement-list> <statement> 

<if-then-statement> ::= "if" "(" <expression> ")" <statement> 

<if-then-else statement> ::= "if" "(" <expression> ")" <statement> 'else' <statement>

<compound-statement> ::= "{" <statement-list> "}"

对于函数声明,<compound-statement> 非终结符是 <function-declaration> 语法产生式右侧的最后一个非终结符。

PS 所有非终结符都是语法产生式。 所有语法产生式都简化为一个或多个非终结符和/或终结符。 终结符是语言关键字。

我知道这就像 7 年的颠簸,但以上所有答案都不正确; 尽管 Robert Cooper 说这会破坏语法是对的。

真正的问题与 C 的原始版本的外观有关:

main(argc, argv)
    char *argv[];
{
    puts("hello world!");
}

默认情况下,C 中的所有内容都是 int,因此可以省略大部分类型注释。 现代 C 与此完全向后兼容,因为人们不想丢弃或更新一堆现有代码。

请注意,函数参数列表之后的类型注释看起来与普通变量声明完全一样。 这是故意这样做的,可能是为了简化原始语法,但这意味着尝试定义一个没有大括号的函数,就像你的例子那样是完全不明确的。

基本上,它无法工作,因为解析器无法区分声明语句和类型注释之间的区别。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM