# Why can't I compile a function using the CHKERRQ macro in PETSc?

I wrote a function to read in the runtime parameters my program takes. This function is in a different file than my main program; the two object files are linked after compilation.

When I compile the file that contains the function I use to read in parameters, I get the following warning:

io.c(43): warning #120: return value type does not match the function type
CHKERRQ(ierr);
^


This only seems to affect the CHEKRRQ() macro, and I don't get this warning when I compile the examples included with PETSc. The only obvious difference is that the example is entirely within one file whereas my program is broken up into multiple files.

Does PETSc support separate compilation, or does some aspect of the CHKERRQ() macro cause problems?

-
What type of value does your function return? int? void? Is this consistent with CHEKRRQ? That is, does the marco assume that your function returns an int? –  Matthew Emmett Mar 22 '12 at 2:52
The function returns void. –  Dan Mar 22 '12 at 3:03
Further to the above, it seems like your function should return PetscErrorCode. Here is the manual page: mcs.anl.gov/petsc/petsc-current/docs/manualpages/Sys/… –  Matthew Emmett Mar 22 '12 at 3:06
Ah, I see... since your function returns void, consider using CHKERRV instead of CHKERRQ (or change your function to return PetscErrorCode instead of void). –  Matthew Emmett Mar 22 '12 at 3:07
@Matthew Emmett: It works! Write that up as an answer and I'll accept it. –  Dan Mar 22 '12 at 3:16

CHKERRQ can only be used in functions that return PetscErrorCode.

The PETSc documentation is reasonably clear here:

CHKERRQ - Checks error code, if non-zero it calls the error handler and then returns

CHKERRQ(n) is fundamentally a macro replacement for:

if (n) return(PetscError(...,n,...));

Although typical usage resembles void CHKERRQ(PetscErrorCode) as described above, for certain uses it is highly inappropriate to use it in this manner as it invokes return(PetscErrorCode). In particular, it cannot be used in functions which return(void) or any other datatype. In these types of functions, you can use CHKERRV() which returns without an error code (bad idea since the error is ignored or if (n) {PetscError(....); return(YourReturnType);} where you may pass back a PETSC_NULL to indicate an error. You can also call CHKERRABORT(comm,n) to have MPI_Abort() returned immediately.

-

CHKERRQ cannot be used inside functions other than main() that don't return PetscErrorCode. This is because the CHKERRQ() macro is basically

if(ierr) {PetscError(..,ierr,..);return ierr;}


From the documentation:

Although typical usage resembles "void CHKERRQ(PetscErrorCode)" as described above, for certain uses it is highly inappropriate to use it in this manner as it invokes return(PetscErrorCode). In particular, it cannot be used in functions which return(void) or any other datatype. In these types of functions, you can use CHKERRV() which returns without an error code (bad idea since the error is ignored or if (n) {PetscError(....); return(YourReturnType);} where you may pass back a PETSC_NULL to indicate an error. You can also call CHKERRABORT(comm,n) to have MPI_Abort() returned immediately.

Basically, any functions that use CHKERRQ() should either return PetscErrorCode themselves or use CHKERRV() instead.

-
CHKERRQ can certainly be used in functions other than main! Both only in functions whose return is PetscErrorCode –  aterrel Mar 24 '12 at 20:45
Thanks for catching that. I've edited my answer to reflect that. –  Dan Mar 24 '12 at 20:50