c/c++语言开发共享“{{}} while(0)”在内核代码中的作用是什么?


可能重复:
当我们定义宏时,do(0)有什么用?
为什么在C / C ++宏中有时会出现无意义的do / while和if / else语句?
C多行宏:do / while(0)vs scope block

我已经看过很多这样的用法,以前我是程序员想要轻松打破一段代码。 为什么我们需要在这里执行while {…} while(0)循环? 我们试图告诉编译器一些东西吗?

例如,在Linux内核2.6.25中,包含/ asm-ia64 / system.h

/* * - clearing psr.i is implicitly serialized (visible by next insn) * - setting psr.i requires data serialization * - we need a stop-bit before reading PSR because we sometimes * write a floating-point register right before reading the PSR * and that writes to PSR.mfl */ #define __local_irq_save(x)  do {  ia64_stop();  (x) = ia64_getreg(_IA64_REG_PSR);  ia64_stop();  ia64_rsm(IA64_PSR_I);  } while (0) 

    它总是在宏中使用,因此在调用之后需要分号,就像调用常规函数一样。

    在你的例子中,你必须写

     __local_irq_save(1); 

     __local_irq_save(1) 

    会导致错误的分号错误。 如果不在那里,那就不会发生这种情况。 如果它只是一个范围,一个简单的大括号对就足够了。

    它允许代码显示在这里:

     if(a) __local_irq_save(x); else ...; // -> if(a) do { .. } while(0); else ...; 

    如果他们只是使用{ .. }你就会得到

     if(a) { ... }; else ...; 

    else不再属于any,因为分号将是下一个语句,并将else与前面的if分开。 将发生编译错误。

    do{ ... } while(0)构造的目的是将一组语句转换为一个可以用a终止的复合语句; 。 你会看到,在C语言中, do/while构造有一个奇怪且不寻常的属性:即使它“作用”作为复合语句,它也需要一个; 在末尾。 C中没有其他复合结构具有此属性。

    由于这个属性,你可以使用do/while来编写多语句宏,它可以安全地用作“普通”函数而不用担心宏内部的内容,如下例所示

     if (/* some condition */) __local_irq_save(x); /* <- we can safely put `;` here */ else /* whatever */; 

    答案已经给出了(因此宏强制a ;当被调用时),但是我已经看到过这种语句的另一种用法:它允许在“循环”中的任何地方调用break,如果需要则提前终止。 基本上是你的同事程序员不会谋杀你的“goto”。

     do { int i = do_something(); if(i == 0) { break; } // Skips the remainder of the logic do_something_else(); } while(0); 

    请注意,这仍然相当混乱,所以我不鼓励使用它。

    看起来它只是用于范围界定。 它类似于:

     if (true) { // Do stuff. } 

    编辑

    我在你的例子中没有看到它,但是其中一个函数调用实际上可能是一个宏,在这种情况下,do / while(0)和if(true)之间存在一个关键区别,即前者允许continuebreak

    它使用宏行为就像一个真实的语句或函数调用。

    语句是{ expression-list }expression; 因此,在定义需要多个表达式的宏时会出现问题,因为如果使用{ }那么如果宏的调用者非常合理地添加了一个语法,则会出现语法错误; 在别的之前。

     if(whatever) f(x); else f(y); 

    如果f()是单个语句宏,那很好,但是如果它是一个宏而且复杂的东西呢? 你最终得到if(...) { s1; s2; }; else ... if(...) { s1; s2; }; else ... if(...) { s1; s2; }; else ...那不起作用。

    因此,宏的编写者必须将其转换为实际函数,将构造包装在单个语句中,或使用gnu扩展。

    do .. while(0)模式是“包裹构造”方法。

    需要了解更多c/c++开发分享“{{}} while(0)”在内核代码中的作用是什么?,也可以关注C/ C++技术分享栏目---计算机技术网(www.ctvol.com)!

      以上就是c/c++开发分享“{{}} while(0)”在内核代码中的作用是什么?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/979665.html

      (0)
      上一篇 2021年12月13日
      下一篇 2021年12月13日

      精彩推荐