宏以避免重复的案例值

时间:2014-12-16 16:14:44

标签: c macros

我在C中使用switch表达式来评估errno变量。根据{{​​1}}的手册页:

EAGAIN或EWOULDBLOCK

send()

由于我的申请必须是便携式的,我必须这样做:

The socket is marked nonblocking and the requested operation would block.
POSIX.1-2001 allows either error to be returned for this case,and does not
require these constants to have the same value, so a portable application
should check for both possibilities.

问题在于,对于某些平台,EWOULDBLOCK和EAGAIN确实具有相同的值,因此在编译时我得到:

switch (errno):
  case EWOULDBLOCK:
  case EAGAIN:
    //do whatever
    break;
  case EINTR:
    //...

所以我认为我可以使用一个宏宏,取决于EWOULDBLOCK和EAGAIN是否具有相同的值,平台将该行添加到代码中或省略它。

关于如何编写该宏的任何想法?

2 个答案:

答案 0 :(得分:8)

类似的东西:

 #if EAGAIN != EWOULDBLOCK
      case EAGAIN:
 #endif
      case EWOULDBLOCK:

编辑:但是如果你要有很多switch switch语句,那么宏会比条件编译好。类似的东西:

 #if EAGAIN == EWOULDBLOCK
 #define MY_AGAIN EAGAIN
 #else
 #define MYAGAIN EAGAIN: case EWOULDBLOCK
 #endif

然后使用它:

 case MY_AGAIN:

你会看到冒号在调用它时不是宏的一部分:

 case ---->MACRO GOES HERE<-----:

然而在第二种情况下,在原始周围文本的上下文中展开时:

 case EAGAIN: case EWOULDBLOCK:
如果在switch语句中明确写出但是完全合法的C代码,那将会非常难看。

答案 1 :(得分:5)

不要使用switch,然后;只需使用

if(errno == EWOULDBLOCK || errno == EAGAIN) {
    ...
}

如果EWOULDBLOCK实际上等于EAGAIN,编译器当然会很乐意将其优化为单个测试。