为什么空表达式在C / C ++中合法?

时间:2009-05-05 11:43:07

标签: c++ c language-design

int main()
{
  int var = 0;; // Typo which compiles just fine
}

11 个答案:

答案 0 :(得分:32)

在定义assert(foo == bar);时,NDEBUG如何将其编译为空?

答案 1 :(得分:13)

这是C和C ++表达NOP的方式。

答案 2 :(得分:10)

显然我们可以这样说

for(;;) {
  // stuff
}

没有那个人谁能活下去?

答案 3 :(得分:8)

我不是语言设计师,但我给出的答案是“为什么不呢?”从语言设计的角度来看,人们希望规则(即语法)尽可能简单。

更不用说“空表达”有用,即

for(i = 0; i< INSANE_NUMBER; i ++);

会死 - 等待(不是很好用,但仍然是使用)。

编辑:正如对此答案的评论所指出的那样,任何有价值的编译器可能忙于等待此循环,并将其优化掉。但是,如果在头部本身(除了i ++之外)有更多有用的东西,我已经看到(奇怪地)使用数据结构遍历,那么我想你仍然可以构造一个空体循环(通过使用/滥用“for”构造。)

答案 4 :(得分:6)

老实说,我不知道这是否是真正的原因,但我认为更有意义的是从编译器实现者的角度考虑它。

大部分编译器是由分析特殊语法类的自动化工具构建的。有用的语法似乎很自然地允许空语句。当它不改变代码的语义时,检测这样的“错误”似乎是不必要的工作。空语句不会执行任何操作,因为编译器不会为这些语句生成代码。

在我看来,这只是“不要修理没有破坏的东西”的结果......

答案 5 :(得分:5)

您希望能够执行

之类的操作
while ( fnorble(the_smurf) == FAILED )
    ;

而不是

while ( fnorble(the_smurf) == FAILED )
    do_nothing_just_because_you_have_to_write_something_here();

但是!请不要在同一行写下空语句,如下所示:

while ( fnorble(the_smurf) == FAILED );

这是混淆读者的一种非常好的方法,因为很容易错过分号,因此认为下一行是循环的主体。请记住:编程实际上是关于通信 - 不是与编译器有关,而是与其他人一起阅读您的代码。 (或者三年后你自己!)

答案 6 :(得分:5)

好的,我会将此添加到您可能实际使用的最坏情况:

for (int yy = 0; yy < nHeight; ++yy)
{
    for (int xx = 0; xx < nWidth; ++xx)
    {
        for (int vv = yy - 3; vv <= yy + 3; ++vv)
        {
            for (int uu = xx - 3; uu <= xx + 3; ++uu)
            {
                if (test(uu, vv))
                {
                    goto Next;
                }
            }
        }

    Next:;
    }
}   

答案 7 :(得分:3)

最常见的情况可能是

int i = 0;
for (/* empty*/; i != 10; ++i) {
    if (x[i].bad) break;
}
if (i != 10) {
    /* panic */
}

答案 8 :(得分:2)

使用&#39;;&#39;请注意一件事。这没关系:

a ? b() : c();

然而,这不会编译:

a ? b() : ; ;

答案 9 :(得分:0)

while(1){
    ; /* do nothing */
}

有时候你想坐下来什么都不做。事件/中断驱动的嵌入式应用程序,或者当您不希望函数退出时,例如在设置线程和等待第一个上下文切换时。

例如: http://lxr.linux.no/linux+v2.6.29/arch/m68k/mac/misc.c#L523

答案 10 :(得分:0)

已经有很多好的答案,但还没有看到生产环境样本。

Here是FreeBSD对strlen

的实现
size_t
strlen(const char *str)
{
    const char *s;

    for (s = str; *s; ++s)
        ;
    return (s - str);
}