开发者

How to reduce redundant code during error checking

开发者 https://www.devze.com 2023-01-19 04:17 出处:网络
NOTE: The restriction is that I cannot use exceptions (the code is eventually compiled with exceptions disabled - not under my control). The project is a real-time 3D graphics application.

NOTE: The restriction is that I cannot use exceptions (the code is eventually compiled with exceptions disabled - not under my control). The project is a real-time 3D graphics application.

I am using my own error class (I had posted a question regarding that not too long ago) which each class uses. Very simple, all it does it records an error during a function call. The function returns that error and it can also be checked by calling SomeClass->GetLastError(). If it is NO_ERROR (all enums) then we can proceed, although we can chose to ignore it (for example if a particular object does not load, we can ignore it, put an ugly pink box in its place and flag an error). A function CreateScene() is called when a State is created which then proceeds to call various function开发者_运维百科s that are responsible for creating the scene. All these functions might potentially return an error. So what I then have is something like this:

if (CreateGrid() != NO_ERROR)
{
  mCore->Terimate();
  mLog->Error("\n[FATAL] Initialization Failed, check error log");
  return;
}
if (SomeOtherFunc() != NO_ERROR)
{
  mCore->Terimate();
  mLog->Error("\n[FATAL] Initialization Failed, check error log");
  return;
}

The functions called might have different function signatures, so the arguments can be different although the return type is always an integer. I have quite a few calls like the one above so I wrote a #define for it which takes in the function as the parameter and is exactly the same as the code above. So now, the above code looks like:

CALL_FUNC(CreateGrid());
CALL_FUNC(SomeOtherFunc());

The define is undefined once I am done with it. Anyway, this is the only idea I could come up with. Even though it has an ugly #define the resulting code is clean. Is there a better technique that I should be using here?

Thanks


Assuming you really don't care which function fails or can determine which one failed by some means other than testing the return value,

if (CreateGrid() != NO_ERROR || SomeOtherFunc() != NO_ERROR)
{
    // Handle error
}


The correct answer is "use exceptions" but it sounds like reasons beyond your control are preventing you using the ideal solution. Here's my alternative: consider goto - considered harmful by some, but perfectly legitimate for C-style error checking. Below is an example, note that all the error handling is in one place, and you know the error code in the error handler, which gains you some of the advantages of exceptions, without actually using exceptions.

int ret;

if ((ret = CreateGrid()) != NO_ERROR)
    goto Error;

if ((ret = SomeOtherFunc()) != NO_ERROR)
    goto Error;

// ...

Error:
mCore->Terminate();
mLog->Error("\n[FATAL] Initialization Failed, check error log");
// Note that here, 'ret' stores the value of the last error code.
// This may be useful for further diagnostics at this point, and you
// probably want to log it too.
return;
0

精彩评论

暂无评论...
验证码 换一张
取 消