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

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

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

如何assert(foo == bar); 在定义NDEBUG时编译为NDEBUG

显然我们可以这样说

 for(;;) { // stuff } 

谁能活下去呢?

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

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

for(i = 0; i

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

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

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

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

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

你希望能够做到这样的事情

 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 ); 

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

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

 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:; } } 

最常见的情况可能是

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

使用’;’时 请注意一件事。 还行吧:

 a ? b() : c(); 

但是这不会编译:

 a ? b() : ; ; 
 while(1){ ; /* do nothing */ } 

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

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

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

这是FreeBSD的strlen实现:

 size_t strlen(const char *str) { const char *s; for (s = str; *s; ++s) ; return (s - str); }