为什么使用 do {} while(0) - yanbin's Blog
为什么使用 do {} while(0)
有些宏定义含有多行代码,一般使用 do {} while(0) 把代码放在 'do' 和 'while' 之间的 '{}' 中。
#define foorbar(msg, callback) do {\ struct Task __task = msg_to_task((msg)); \ if (__task != NULL) { \ process(__task, (callback)); \ char *__msg = task_to_msg(__task); \ if (__msg != NULL) \ { send_msg(__msg); \ free(__msg); \ } \ destroy_task(__task); \ } while (0)
这样用的原因是:
1.符合 C/C++ 语法习惯。
每条语句后面都一个';', 而 do {} while 语句后面也要加一个 ';'.
2.避免出现语法错误。
不用 do {} while(0) 把多行代码包起来,在 if else 语句中就会有语法错误,例如:
#define foorbar(a, b) foor((a)); bar((b)) if (something) /* 以下有语法错误 */ foorbar(3, 2); else // do something
仅仅使用 '{}' 把多行代码包起来,如果在调用宏之后加 ';', 也会有语法错误。
#define foorbar(a, b) {\ foor((a)); bar((b));\ } foorbar(3, 2); // 此处有语法错误 /* 编译器提示: * error: expected ‘;’ before ‘}’ token * 如果不加 ';', 不会有语法错误但是这样不符合 C/C++ 的语法习惯 */
3.do {} while(0) 可以根据条件跳出执行。
#define foorbar() do {\ struct condition __cond; \ if (__cond.wait_cond()) \ break; // 条件发生退出执行 \ // 条件没有发生 do something } while(0)
4.私以为 do {} while(0) 可以保证代码执行并且只执行一次。
5.需要注意的地方。
(a)宏定义时用 '\' 连接多行语句;
(b)宏定义中定义变量,注意与外部变量名字冲突,不然原本希望用外面的变量,却用了新定义的变量。
(c)有些编译器会优化掉 do {} while(0); 直接展开 '{}' 内的代码, 如(b)所描述,此时会出现语法错误。
FIXME: 如果内部有 'break' 并且 'break' 的执行依赖运行时条件,编译器就不会优化掉 do {} while(0); 了。
举例:
#define foorbar() do {\ struct condition cond; \ if (cond.wait_cond()) \ break; // 条件发生退出执行 \ // 条件没有发生 do something } while(0) struct condition cond; // do something foobar(); // 到底用的是哪一个 cond?
#define foorbar(a, b) do {\ const char *something = get_something(a, b); \ } while(0) const char *something; // do something foorbar(3, 9); // 如果编译器优化掉了 do {} while(0); 这里有语法错误。
感谢 老猫,mike2,MovableType@源赖朝 三位网友。
参考:
do { … } while (0) — what is it good for?
do{}while(0) 的作用
2018年7月24日 11:23
Thanks for the information on the site.
2018年7月24日 11:23
Thanks for the information on the site.
2019年8月23日 14:16
I really happy found this website eventually. Really informative and inoperative, Thanks for the post and effort! Please keep sharing more such blog. Now I saved it to my bookmarks so that I can keep me in touch with you.
2020年6月25日 17:40
Install this amazing game which was introduced by David Baszucki and Erik cassel in 2004.
2020年9月06日 04:51
thankyou for the information windows 10 is most popular operating system. It has new mode to know more visit at https://windows10download.xyz
2021年5月20日 18:51
Visit here and download the complete solutions of class 11th Mathematics solutions in free of cost.
2022年11月24日 12:36
Do {} while(0) is a construct that is used to ensure that a statement is always executed at least once. It is often Atlantis Park Orange County used in situations where a statement is required to be executed, but the condition that determines whether or not to execute the statement may not be known until after the statement has been executed.
2023年1月14日 10:33
There are a few reasons for why you might want to use do {} while(0) in your code. One reason is that it can help to make your code more readable. For example, if you have a lot of if/else statements, using do {} while(0) can help to make it clearer which statement goes with which if/else. Another reason is that do {} while(0) can help to prevent accidental infinite loops. If Buy CBD you forget to put a break statement in your code, using do {} while(0) will ensure that your code doesn't get stuck in an infinite loop.
2023年9月19日 18:52
BSE Odisha Provides the Syllabus for All the 8th This new Syllabus are Designed Strategically by a Team of Subject Experts and are Prescribed by the Department of School and Mass Education, Government of Odisha level Syllabus for the Children of Odisha has been developed with the supervision of the Department of School and Mass Education, Government of Odisha.one Needs to have BSE Odisha 8th Class Syllabus 2024 a good Understanding of the Odisha Exam Pattern and Syllabus 2024, If the Students know the Syllabus of the Exam, then they can Direct their Preparation in the best way.