关于一种宏的用法解释

关于这种用法(winsock2.h中)
#define FD_SET1(fd, set) do{/
//some codes fragment;
}while(0)

此宏一般用于嵌入一段代码段,或是用宏来封装一段可重用的代码。
当然也可写为
#define FD_SET2(fd, set){/
//some codes fragment;
}
这两段宏定义表达的本质是完全相同的。
但是当我们使用的时候却有些不同。

如下分析:

举例如下
(1)使用带大括号
if (condition){
   FD_SET1(fd,set);
}
else
{
   //other codes.
}

(2)不使用大括号
if (condition)
   FD_SET1(fd,set);
else
{
   //other codes.
}
当宏展开时,这个完全没问题,也没有任何多余的符号。
if (condition)
    do{/
    //some codes fragment;
      }while(0);
else
{
   //other codes.
}
因为do while后面本来就有一个分号来终止。

但是当使用第二个宏时,就存在潜在的错误。
(1)带大括号,这个使用没有问题。
只是这里的这个分号时多余的。

if (condition){
   FD_SET2(fd,set);
}
else
{
   //other codes.
}
(2)不使用大括号,如下使用就有问题了。
if (condition)
   FD_SET2(fd,set);
else
{
  
}
展开后为
if (condition)
{
   //code fragments;
};
else
{

}
显然,这里多了一个分号,而且这是错误的。 分号表示上面的if语句已经结束,故会显示如下错误
error C2181: illegal else without matching if。

综上所述,当使用第一种宏的定义时,在任何情况下都是正确的, 而第二种在某些情况下会导致错误。
这就是这种写法的缘由所在。

你可能感兴趣的:(c)