开发者

Macro to log error and return false

Most of the statements in the project I work with is of the form

if(!someObject->someFunction(arg1,arg2))
{
    cerr << "Something bad happened. Args are: " << arg1.print() << " " << arg2  << endl;
    return false;
}

This makes my code not readable as error logging triples the 开发者_高级运维actual code. Hence I wrote the following macro,

#define ReturnFalse(error) \
  ({ \
   cerr << error << "@File: " << __FILE__ << "Line: " << __LINE__ << endl; \
   return false; \
   false; \
   }) \

Now I can use it as,

someObject->someFunction(arg1,arg2) || ReturnFalse("Something bad happened.Args are:" << arg1.print() << " " << arg2 );

This works but I am afraid if I am following bad practice.

  1. Is the code illegal/undefined?
  2. In performance wise, is it any worse than if?
  3. My vim does not recognize the formatting and highlight as if there is some syntax error. Is there anyway to fix this?
  4. Is there a better way to log a message and return with a neat syntax?
  5. It is not straight forward that the macro could return from the function. So I named it ReturnFalse. Can anyone suggest a better name?

Edit:

Thanks for all replies.Is there a standard way to do it using comma operators? I am not able to get it right.


The code is not C++ standard conforming and non portable.

({..})

is a gcc compiler extension called as Statement Expression.

If you compile your code with -pedantic flag & it will tell you that it is non Standard conforming.

Unless you are not worried about the portability of your source code across different compilers, you should refrain from using any code constructs which are not supported by the C++ Standard and are just compiler extensions.


I think that it would better be a function:

bool fnAssert(bool cond, char * strCond, char *msg, char *file, int line)
{
    if (!cond)
    {
        cerr << "@File: " << file << ":" << line << " " << strCond << " failed."
              << msg << endl;
    }
    return cond;
}

#define Assert(cond, a) fnAssert(cond, #cond, a, __FILE__, __LINE__)

This way it is portable to all compilers, will show syntax highlighting, and the macro allows automatically inserting the file name and the line number. You'll also be able to print the failed condition, and put breakpoints when you debug it.

edit

Although it's very ugly and I advise you strongly not to do that, here's a way to automatically return on assert from within the code (using the above macros):

#define ReturnOnAssert(cond, a, b) if (! Assert(cond,a) ) return b;

Now when you write a statement:

ReturnOnAssert(isItBad, "Something bad happened", retVal);

or

DoWhatever(), ReturnOnAssert(isItBad, "Something bad happenedAgain", retVal);

You'll return from your function with the value retVal, if isItBad is false.

BUT - hiding return in a macro is a big NO-NO IMHO. Don't do that. What are you trying to save, 2 lines of code on an if?


When you want a better method of error handling in a C++ program, you should probably have a look at the Appendix E of the TCPL Special Edition. It is better to avoid macro magic if you can. The appendix discusses techniques to be used while handling errors. This is also available at: http://www2.research.att.com/~bs/3rd_safe.pdf

EDIT: And for the macro magic case using the comma... This might be a possible way:

 #define ReturnFalse(error,a1,a2) \
 ({ \
  cerr << error << "@File: " << __FILE__ << "Line: " << __LINE__ << #a1<<" "<<#a2 <<endl; \
  return false; \
  false; \
 })

use case: ReturnFalse("Something bad happened.", arg1 , arg2)

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜