do {} while(0) 经常用在宏的定义中。这就是C语言的一个常见的用法,简称惯用法。任何一门语言都会有若干惯用法,有“经验”的程序员是应当知悉这些惯用法的。
除了惯用法,还有模式,这是更高层次的经验积累。当遇到一个“问题”,要知道这个问题并不是“新问题”,而是在若干年前都被无数人解决过多次。前辈们把这些已经解决过的问题进行了分类、提炼,就形成了若干模式。
在模式的基础之上,还可以形成架构,这就是基于模式的架构。一个程序员如果要具有驾驭“大系统”的能力,需要知悉若干常用的架构。
好了,不扯远了,下面具体说一下 do {}while (0)这种惯用法。
将 do {} while (0) 用在宏里面是最恰当不过的了。
假设某一宏的定义如下:
#define TEST_MACRO(a, b, c) /
a = c; b = c;
当程序这样来使用宏时:
if (condition)
TEST_MACRO(a, b, c);
宏被替换后就变成了:
if (condition)
a = c;
b = c;
显然,这与原来的意图相悖。很容易我们就通过更改以上的宏定义将其加上 {} 来达到目的。但这样也是不可取的。如:
#define TEST_MACRO(a, b, c) /
{a = c; b = c;}
if (condition)
TEST_MACRO(a, b, c);
else
do_something_else();
宏展开后:
if (condition)
{
a = c;
b = c;
}
; /* <--- here !!! */
else
do_something_else();
我想您已经看出来这里面的原因了。编译器是不会放过你的。
但,如果利用 do {} while(0) 定义的话,这些都可以避免了。
#define TEST_MACRO(a, b, c) /
do { a = c; b = c; } while(0)
除了惯用法,还有模式,这是更高层次的经验积累。当遇到一个“问题”,要知道这个问题并不是“新问题”,而是在若干年前都被无数人解决过多次。前辈们把这些已经解决过的问题进行了分类、提炼,就形成了若干模式。
在模式的基础之上,还可以形成架构,这就是基于模式的架构。一个程序员如果要具有驾驭“大系统”的能力,需要知悉若干常用的架构。
好了,不扯远了,下面具体说一下 do {}while (0)这种惯用法。
将 do {} while (0) 用在宏里面是最恰当不过的了。
假设某一宏的定义如下:
#define TEST_MACRO(a, b, c) /
a = c; b = c;
当程序这样来使用宏时:
if (condition)
TEST_MACRO(a, b, c);
宏被替换后就变成了:
if (condition)
a = c;
b = c;
显然,这与原来的意图相悖。很容易我们就通过更改以上的宏定义将其加上 {} 来达到目的。但这样也是不可取的。如:
#define TEST_MACRO(a, b, c) /
{a = c; b = c;}
if (condition)
TEST_MACRO(a, b, c);
else
do_something_else();
宏展开后:
if (condition)
{
a = c;
b = c;
}
; /* <--- here !!! */
else
do_something_else();
我想您已经看出来这里面的原因了。编译器是不会放过你的。
但,如果利用 do {} while(0) 定义的话,这些都可以避免了。
#define TEST_MACRO(a, b, c) /
do { a = c; b = c; } while(0)