likask
likask

Reputation: 215

clang-format Function and error check in the same line

I struggle to set up clang-format to allow short lines for such format,

ierr = fun(); CHKERRQ(ierr);

clang-format break the line, as result

 ierr = fun(); 
 CHKERRQ(ierr);

It is a solution to stop clang-fromat to break short lines? Or this is in principle wrong idea to format code like this. Any advice very appreciated.


EDIT: Following Guillaume answer

In fact, I have a slightly more complex problem, where errors codes of different types are returned by two libraries, in particular, PETSc and MoAB. Also, this system has own error codes, which need to be handled. All without compromising efficiency.

struct ErrorCheckerCode {
  inline void operator<<(const MoFEMErrorCode err) {
    if (PetscUnlikely(err)) {
      // Handle & thorw PETSc/MoFEM error
    }
    return;
  }
  inline void
  operator<<(const moab::ErrorCode err) {
    if (PetscLikely(MB_SUCCESS != err)) {
      // Handle & trow MOAB error 
    }
    return;
  }
  static const char *fUNC;
  static const char *fILE;
  static int lINE;
};

struct ErrorCheckerFunction {
  inline ErrorCheckerCode operator<<(const char *func) {
    ErrorCheckerCode::fUNC = func;
    return ErrorCheckerCode();
  }
 };

struct ErrorCheckerFile {
  inline ErrorCheckerFunction operator<<(const char *file) {
    ErrorCheckerCode::fILE = file;
    return ErrorCheckerFunction();
  }
};

struct ErrorCheckerLine {
  inline ErrorCheckerFile operator<<(int line) {
    ErrorCheckerCode::lINE = line;
    return ErrorCheckerFile();
  }
};

And definition follows this:

#define CHKERR                                                                 \
  ErrorCheckerLine() << __LINE__ << __FILE__ << PETSC_FUNCTION_NAME <<

So at the end I can handle errors like this

CHKERR fun_moab();
CHKERR fun_petsc();
CHKERR fun_mofem();

This implementation is essential, so it has to be done optimally, I wonder if that can be done in simpler, more efficient way. Criticism or advice is very welcome.

Note:

As a commend. It is funny how formatting of code triggers this type of developments.

Upvotes: 3

Views: 769

Answers (1)

Guillaume Gris
Guillaume Gris

Reputation: 2270

I use clang-format a lot and I don't think it can achieve this kind of formatting.

I've encountered this pattern a lot in libraries using OpenGL and DirectX. You have a API with error codes or an error stack like in OpenGL and every function might fail or issue a warning. You want your code to be optimized in release and still have a debug mode to find preciselly where things went wrong in case you spot a bug.

Some libraries provide some kind of error callback that you can set and will effectively be called each time there is a relevent error.

In case you want something more customized or no error callback is provided, you can write a simple wrapper that does a systematic error checking and warnings logging.

With these solutions you can even implement some mechanism to activate the debugging at runtime.

Now, if you are writing the library or functions that return errors returned this way, you might want to include the debug mode directly in the library with the debug callback strategy.


Now, if you want to stick to the macro solution, you could do the following:

struct ErrorChecker
{
    ErrorChecker& operator << (int ierr)
    {
        // Error checking code
        return *this;
    }
};

#define CHKERR ErrorChecker() <<

and then

CHKERR fun();

Upvotes: 1

Related Questions