Do..while (0) C function macrogrid in c2hs

I would like to put a macro of type C in a C function (and in turn wrap it in Haskell with a block {#fun ... #}

), but the preprocessor will c2hs

slam into the syntax do.. while(0)

; here's the code:

module TestMacro where

#define TestF1(n) do{if n==0 return 0;else return 1; } while(0)

int c_testF1(int x)
{ return ( TestF1(x) ); }



and here's the error:

c2hs TestMacro.chs
c2hs: C header contains errors:

TestMacro.chs.h:6: (column 12) [ERROR]  >>> Syntax error !
  The symbol `do' does not fit here.

make: *** [main] Error 1


What am I doing wrong? My goal is to wrap a CHKERRQ

PETSc library macro defined in the petscerror.h

following way: (split over multiple lines for readability):

#define CHKERRQ(n)             
    do {if (PetscUnlikely(n)) 
    while (0)



source to share

2 answers

Remember, this #define

is a text replacement. So,

{ return ( TestF1(c) ); }



{ return ( do{if c==0 return 0;else return 1; } while(0) ); }


and you cannot use do { .. } while()

other operators return

as return parameters (and there are Γ¬f

no parentheses around the condition ). To make your macro work at this point, it could simply be defined as

#define TestF1(n)    ((n)==0 ? 0 : 1)



The function using CHKERRQ

might look like this:

int my_chkerrq( int n )
     return( whatever_you_want_to_return_here );


but I would suggest directly triggering the calls CHKERRQ()


int my_chkerrq( int n )
     if (PetscUnlikely(n)) 
         return( whatever_you_want_to_return_here );


Of course, in both cases __LINE__

and __FILE__

are replaced by C code values ​​and may not be very useful in the Haskell environment



{ return ( TestF1(c) ); }


The syntax return

requires an expression (optional): you cannot use an operator instead of an expression. do {} while (0)

- this statement.

(C11, 6.8.6. Jump Operators)


return expression_opt;

What you can do is use instead:

int c_testF1(int x)
{ TestF1(c); }


As I added in the comments, it would work, but I don't advise doing it, it's bad coding style. ?:

can be used in an example macro TestF1

(as written in another answer), but it cannot be used for your real use case CHKERRQ

(you can use a macro to call a function PetscError




All Articles