print_once,它是如何工作的blockwise? [英] print_once, how blockwise it is working?

查看:152
本文介绍了print_once,它是如何工作的blockwise?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图理解一次打印一次函数,这段代码工作正常;
但是我无法理解一些事情:
1)这是如何分块的?也许我无法正确清除它,但只是想知道 C 的哪些属性能够实现这一点?

  1 #include  
2
3 #define _TRACE_
4
5 #ifdef _TRACE_
6 #define print_once(fmt,...)\
7({ \
8 static bool __print_once = false; \
9 if(!__ print_once){\
10 __print_once = true; \
11 do {\
12 printf(fmt,## __ VA_ARGS__); \
13} while(0); \
14} \
15})
16 #else
17 #define print_once(fmt,...)\
18 printf(\\\
);
19 #endif
20
21 void func()
22 {
23 print_once(func\\\
);
24}
25 int main(int argc,char * argv [])
26 {
27 print_once(test1\\\
);
28 //:w
29 print_once(test22\\\
);
30 for(int i = 0; i <2; i ++)
31 print_once(loop \ n);
32 func();
33 func();
34返回0;
35}


解决方案

它使用名为语句表达式的GCC扩展(<({...})语法)。 (它也不是线程安全的。)



它通过在每个 print_once 调用站点上添加一个静态布尔值每个调用站点都有它自己的静态标志),最初是 false ,它在第一次运行这段代码时被设置为true(代码仅当它确实)。因此,后续执行相同的代码块将不会打印任何内容。



请注意,不需要使用GCC扩展,并且构建宏很奇怪 - 它可能从更简单的事情扩展而来。这应该与C99兼容( variadic宏所需的C99或更高版本),并具有 do {...} while(0)trickin the right place:

  #define print_once(fmt,...)\ 
do {static bool flag = false; \
if(!flag){\
flag = true; \
printf(fmt,## __ VA_ARGS__); \
} \
} while(0)


I am trying to understand implement a print once function, this code is working fine; But I am not able to understand some things: 1) How blockwise this is working? Maybe I am not able to clear it properly, but just want to know, what property of C make this happen?

  1 #include <stdio.h>
  2 
  3 #define _TRACE_
  4 
  5 #ifdef _TRACE_
  6 #define print_once(fmt, ...)            \
  7 ({                                      \
  8      static bool __print_once=false;           \
  9      if(!__print_once)    {               \
 10          __print_once = true;           \
 11          do  {                               \
 12             printf(fmt, ##__VA_ARGS__);   \
 13         }while(0);                          \
 14      }                                  \
 15 })
 16 #else
 17 #define print_once(fmt, ...)    \
 18 printf("\n");                   
 19 #endif
 20 
 21 void func()
 22 {
 23     print_once("func\n");
 24 }
 25 int main(int argc, char* argv[])
 26 {
 27     print_once("test1\n");
 28     //:w
 29     print_once("test22\n");
 30     for(int i =0; i < 2; i++)
 31         print_once("loop\n");
 32     func();
 33     func();
 34     return 0;
 35 }

解决方案

That's not standard C, it uses a GCC extension called statement expressions (the funny ({...}) syntax). (It's not thread-safe either.)

It works by adding a static boolean at each print_once call site (each call site gets its own static flag), initially false, which is set to true the first time that piece of code is run (the code only prints if it was indeed false). So subsequent executions of the same block of code won't print anything.

Note that the use of the GCC extension is not necessary, and the construction of the macro is strange - it was probably extended from something simpler. This should be C99-compatible (C99 or above required for the variadic macro), and has the do {...} while(0) "trick" in the right place:

#define print_once(fmt, ...) \
do { static bool flag = false;  \
     if (!flag) { \
       flag = true; \
       printf(fmt, ##__VA_ARGS__); \
     } \
} while (0)

这篇关于print_once,它是如何工作的blockwise?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆