1

I have a scenario in the code where the following pattern exist -

if (!function(A))
{
   log("this is the %d error in this file called %s", num, fileName);
   throw AppException(FUNCTION_ERROR);
}

the issue with this is you need to do this all the time and the code looks really dirty. so I want to define a macro like -

#define VerifyOrThrow(b, retcode, logerror)
        if (b == 0)                                         \
        {                                                   \
            log(logerror,arg1, arg2)  -->this is the issue        \
            throw(AppException(retcode));                   \
        }

then I can use it like this in a single line

VerifyOrThrow(functionA(), FUNCTION_ERROR,this is the %d error in this file called %s);

The issue is I am not sure how to define the macro for the variable length argument for the log string.

Any ideas?

Philip
  • 5,795
  • 3
  • 33
  • 68
Sriram Subramanian
  • 2,623
  • 5
  • 32
  • 35
  • http://en.wikipedia.org/wiki/Variadic_macro –  Apr 26 '11 at 08:57
  • i guess i could extend the macro to define any number of arguments and just pass them to the log method. That is a possible solution. Wanted to see if there is any other elegant solution to this. – Sriram Subramanian Apr 26 '11 at 08:58

2 Answers2

3

Use __VA_ARGS__ as:

#define VerifyOrThrow(b, retcode, ...)
        if (b == 0)                                         \
        {                                                   \
            log(__VA_ARGS__);                               \
            throw(AppException(retcode));                   \
        }
Nawaz
  • 353,942
  • 115
  • 666
  • 851
2

My favourite logging macro in C++:

#define ATHROW( msg )                                               \
{                                                                   \
    std::ostringstream os;                                          \
    os << msg;                                                      \
    throw ALib::Exception( os.str(), __LINE__, __FILE__ );          \
}           

In this case, I throw an exception, but you could do whatever you want after you have formatted the string. In use:

ATHROW( "The value of x is " << x << " when it should be " << correct );

This has all the advantages of the C++ stream output system - type safety, extensibility etc. It is also portable, which the use of variadic macros is currently not (they are not part of the current C++ standard).

  • 1
    would benefit from the `do { ... } while (0)` [macro trick](http://stackoverflow.com/questions/154136/why-are-there-sometimes-meaningless-do-while-and-if-else-statements-in-c-c-macr). – Philip Potter Apr 26 '11 at 09:11
  • @Philip. Yes. But I have been using this and similar macros for 25 years or more and have never once been bitten by the problems that the while trick is supposed to circumvent. So I have given up bothering about it. –  Apr 26 '11 at 09:12