我们在嵌入式开发的过程中,经常可以碰到在一些宏定义或者是代码段中使用了do {...} while(0)的语句,从语义上理解,do {...} while(0)内的逻辑就只执行一次,并没有循环执行,粗略看来,似乎画蛇添足了,那么为什么还需要在只执行一次的逻辑外面加上一层do {...} while(0)语句呢?实际上,在这些逻辑中使用d...
do_something(); 错误出在“;”直接位于代码块的后面,解决的办法是将代码嵌入do...while(0),于是得到下面的代码: if (x > y) do { int tmp; tmp = x; x = y; y = tmp; } while(0); else do_something(); 于是上面的宏可以修改为: #define exch(x,y) do { int tmp; tmp = x; x =...
代码冗余是消除了,但是我们引入了C++中身份比较微妙的goto语句,虽然正确的使用goto可以大大提高程序的灵活性与简洁性,但太灵活的东西往往是很危险的,它会让我们的程序捉摸不定,那么怎么才能避免使用goto语句,又能消除代码冗余呢,请看do...while(0)循环: boolExecute(){// 分配资源int*p =newint;boolbOk(true);...
宏被展开后,上面的调用语句会保留初始的语义,同时绝大部分编译器都能够识别do{...}while(0)这种无用的循环并进行优化,不会导致性能优化的降低。 小结 在Linux内核和驱动代码还有cocos2d-x中,很多宏实现都使用do{...}while(0)来包裹他们的逻辑,Google的Robert Love(先前从事Linux内核开发)给我们解答如下: “ 让...
} } while(0) 熟悉Lwip(Light Weight (轻型)IP协议)的小伙伴,应该比较熟悉上述两个示例。在Lwip中,会经常看到宏定义do{...}while(0)的结构。如上示例可以看出,使用宏替换多条语句的编写,会方便的多。但是,为什么要使用do{...}while(0)这样的结构形式呢?答:使用do{...}while(0)构造后的宏定义,可避免...
在Linux 内核中,经常会看到do{} while(0)这样的语句,许多人开始都会疑惑,认为do{} while(0)毫无意义,因为它只会执行一次,加不加do{} while(0)效果是完全一样的,其实do {}while(0)的用法主要用于宏定义中。
先看这句话:do{...}while(0)在C中是唯一的构造程序,让你定义的宏总是以相同的方式工作,这样不管怎么使用宏(尤其在没有用大括号包围调用宏的语句),宏后面的分号也是相同的效果。这句话的意思是说,在宏定义中使用do...while(0)包含的所有语句是一个代码块,不会受到{};的影响。
可预测的展开:do { ... } while(0)结构确保了宏的展开是可预测的,不会因为调用上下文的不同而改变行为。 便于调试:当宏被展开时,do { ... } while(0)结构使得调试器可以更容易地识别和跟踪宏内部的语句。 最核心的作用 使用do { ... } while(0)结构确保了无论n的值如何,宏展开后都是一个完整的...
do_something_useful(blah);; 1. 2. 3. 这样,if条件之后包含了printf()语句,而do_something_useful()调用不能按照预期那样工作。而是用do {...} while(0)定义后,就会展开成以下语句: if (blah == 2) do{ printf("arg is %s\n", blah); ...
如果没有使用do{}while(0)定义这样的宏,进而在if语句后扩展这样的宏又没用{}括起来,会导致宏展开后语法逻辑错误。故这也是为什么单条if else语句也推荐使用{}括起来的原因之一。 使用do{….}while(0) 把它包裹起来,成为一个独立的语法单元,从而不会与上下文发生混淆。并且可以在宏之后添加分号,符合语句结束添加...