Skip to main content
`Ctrl`+`K`

# PetscMacroReturns

Define a macro body that returns a value

## Synopsis

    #include <petscmacros.h>
    return_type PetscMacroReturns(return_type retexpr, ...)

## Input Parameters

- retexpr - The value or expression that the macro should return

- VA_ARGS - The body of the macro

## Notes

Due to limitations of the C-preprocessor retexpr cannot depend on symbols declared in the body of the macro and should not depend on values produced as a result of the expression. The user should not assume that the result of this macro is equivalent to a single logical source line. It is not portable to use macros defined using this one in conditional or loop bodies without enclosing them in curly braces:

      #define FOO(arg1) PetscMacroReturns(0,arg1+=10) // returns 0

      int err,x = 10;

      if (...) err = FOO(x);      // ERROR, body of FOO() executed outside the if statement
      if (...) { err = FOO(x); }  // OK

      for (...) err = FOO(x);     // ERROR, body of FOO() executed outside the loop
      for (...) { err = FOO(x); } // OK

It is also not portable to use this macro directly inside function call, conditional, loop, or switch statements:

      extern void bar(int);

      int ret = FOO(x);

      bar(FOO(x)); // ERROR, may not compile
      bar(ret);    // OK

      if (FOO(x))  // ERROR, may not compile
      if (ret)     // OK

## Example usage

      #define MY_SIMPLE_RETURNING_MACRO(arg1) PetscMacroReturns(0,arg1+=10)

      int x = 10;
      int err = MY_SIMPLE_RETURNING_MACRO(x); // err = 0, x = 20

      // multiline macros allowed, but must declare with line continuation as usual
      #define MY_COMPLEX_RETURNING_MACRO(arg1) PetscMacroReturns(0, \
        if (arg1 > 10) {                                            \
          puts("big int!");                                         \
        } else {                                                    \
          return 7355608;                                           \
        }                                                           \
      )

      // if retexpr contains commas, must enclose it with braces
      #define MY_COMPLEX_RETEXPR_MACRO_1() PetscMacroReturns(x+=10,0,body...)
      #define MY_COMPLEX_RETEXPR_MACRO_2() PetscMacroReturns((x+=10,0),body...)

      int x = 10;
      int y = MY_COMPLEX_RETEXPR_MACRO_1(); // ERROR, y = x = 20 not 0
      int z = MY_COMPLEX_RETEXPR_MACRO_2(); // OK, y = 0, x = 20

## See Also

`PetscExpand()`, `PetscConcat()`, `PetscStringize()`

## Level

intermediate

## Location

include/petscmacros.h

Index of all Sys routines
Table of Contents for all manual pages
Index of all manual pages