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
#c

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

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

#endc

      

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)) 
        return PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,n,PETSC_ERROR_REPEAT," ");} 
    while (0)

      

+3


source to share


2 answers


Remember, this #define

is a text replacement. So,

{ return ( TestF1(c) ); }

      

becomes

{ 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)

      



Edit

The function using CHKERRQ

might look like this:

int my_chkerrq( int n )
{
     CHKERRQ(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( PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,n,PETSC_ERROR_REPEAT," ") );
     else 
         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

+9


source


{ 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)

Syntax

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

though).

+5


source







All Articles