Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Macro to avoid duplicate case value

Tags:

c

macros

I am using a switch expression in C in order to evaluate the errno variable. According to the man page for send():

EAGAIN or EWOULDBLOCK

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.

Since my application must be portable, I have to do:

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

The problem is that for some platforms, EWOULDBLOCK and EAGAIN do have the same value, so when compiling I get:

 connection.cxx:190:5: error: duplicate case value
 case EWOULDBLOCK:
 ^
 connection.cxx:189:5: error: previously used here
 case EAGAIN:
 ^

So I thought I could use a macro macro that depending on whether EWOULDBLOCK and EAGAIN have the same value or not for the platform adds that line to the code or omits it.

Any idea on how to write that macro?

like image 642
user2891462 Avatar asked Dec 16 '14 16:12

user2891462


2 Answers

Something like:

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

edit: however if you're going to have many switch switch statements, a macro would be better than the conditional compilation. Something like:

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

Then to use it:

 case MY_AGAIN:

You'll see that the colon is not part of the macro at the point where it is called:

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

however in the second case, when expanded in the context of the original surrounding text:

 case EAGAIN: case EWOULDBLOCK:

that would be real ugly if it were written explicitly within your switch statement but is perfectly legal C code.

like image 173
Mike Crawford Avatar answered Nov 17 '22 05:11

Mike Crawford


Don't use a switch, then; just use

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

The compiler of course will happily optimize this to a single test if EWOULDBLOCK is in fact equal to EAGAIN.

like image 29
nneonneo Avatar answered Nov 17 '22 04:11

nneonneo