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

```none
  #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:

```none
  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
```none
  #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
<A HREF="PETSC_DOC_OUT_ROOT_PLACEHOLDER/include/petscmacros.h.html#PetscMacroReturns">include/petscmacros.h</A>


---
[Edit on GitLab](https://gitlab.com/petsc/petsc/-/edit/release/include/petscmacros.h)


[Index of all Sys routines](index.md)  
[Table of Contents for all manual pages](/docs/manualpages/index.md)  
[Index of all manual pages](/docs/manualpages/singleindex.md)  
