【发布时间】:2011-04-15 16:26:45
【问题描述】:
为什么要编译:
int main()
{
{}
}
但这不是:
{}
int main()
{
}
【问题讨论】:
为什么要编译:
int main()
{
{}
}
但这不是:
{}
int main()
{
}
【问题讨论】:
第一种情况,您在函数内定义一个块,这是允许的(它限制了可见性)。 第二种情况,你定义了一个匿名块,这是不允许的(它需要在函数定义之前,否则编译器永远不知道它什么时候必须执行它)
【讨论】:
{} 是一个无所事事的语句(特别是在 C 语法中,它是一个空的 compound-statement)。您可以将语句放在函数中。你不能把陈述放在别处。
我认为标准不禁止在您的第一个示例中使用空语句的原因是,尽管它没有意义,但它没有害处,并且引入关于何时允许大括号为空的规则会使语法复杂化而无益。
而且,为了迂腐,我想我应该指出,语法也没有在文件范围内定义任何其他构造,其中{} 是一个有效实例,这就是为什么第二个一个是无效的。
【讨论】:
{} 的语句是有效的。没有其他地方允许声明。 {} 还有其他用途(命名空间、类、结构、联合、枚举、初始化程序、链接规范),但所有这些都需要更多的标记才能成为有效的语法,而不仅仅是 {}。
DBG 扩展为空时,简单的{ DBG("Hello"); } 将无法编译,这将是令人惊讶的。
assert 宏在被禁用时不会产生任何结果,它会导致 (void)0 或类似的结果。而且您的 DBG 宏不会导致空复合语句 {},它会导致 {;}:包含空语句的复合语句。当然,有时有空的复合语句很有用,宏就是一个例子,但考虑到assert 的定义方式,我不想出去说标准委员会期望 人们编写的宏最终会扩展为空,因为他们自己避免了这种情况。
{} 在文件范围内单独有效。命名空间定义以关键字命名空间和可选的名称开头,因此{} 在此之后有效,但不是单独有效。就此而言,C++ 中的 struct foo {}; 是有效的,但这也不意味着 {} 本身就是有效的。在 C 和 C++ 中,void foo() {} 是有效的 - 同样不允许在没有介绍的情况下仅使用 {}。
因为在 C 中不允许在全局范围内定义代码。请记住,在 C 中,除变量声明/初始化之外的每一行代码都必须位于函数中。
如果你在inside一个函数,你可以拥有所有你想要的{}块。
【讨论】:
因为唯一可能出现在翻译单元顶层的东西是声明或函数定义;复合语句(是否为空)可能不会出现在该级别。
【讨论】: