3

Im trying to make a generic function to display error messages, with the possibility that the program should exit after the message has been displayed.

I want the function to show the source file and line at which the error occurred.

argument list:

1.char *desc //description of the error
2.char *file_name //source file from which the function has been called
3.u_int line //line at which the function has been called
4.bool bexit=false //true if the program should exit after displaying the error
5.int code=0 //exit code

Because of (4) and (5) i need to use default arguments in the function definition, since i don't want them to be specified unless the program should exit.

Because of (2) and (3) i need to use a macro that redirects to the raw function, like this one:

#define Error(desc, ???) _Error(desc,__FILE,__LINE__, ???)

The problem is that i don't see how those 2 elements should work together.

Example of how it should look like:

if(!RegisterClassEx(&wndcls))
    Error("Failed to register class",true,1); //displays the error and exits with exit code 1

if(!p)
    Error("Invalid pointer"); //displays the error and continues
lazy_banana
  • 450
  • 5
  • 10
  • 1
    http://stackoverflow.com/questions/679979/how-to-make-a-variadic-macro-variable-number-of-arguments (and maybe http://stackoverflow.com/questions/10582500/c-macro-and-default-arguments-in-function) – Vlad May 14 '12 at 11:56
  • adding the '##' before __VA_ARGS__ worked indeed, i tried using variadic macros before, but without ## it didn't worked, thanks – lazy_banana May 14 '12 at 12:04

1 Answers1

1

You cannot overload macros in C99 -- you will need two different macros. With C11, there is some hope using _Generic.

I had developed something very similar -- a custom warning generator snippet for Visual Studio -- using macros. GNU GCC has some similar settings for compatibility with MSVS.

#define STR2(x) #x
#define STR1(x) STR2(x)
#define LOC __FILE__ “(“STR1(__LINE__)”) : Warning Msg: “
#define ERROR_BUILDER(x) printf(__FILE__ " (“STR1(__LINE__)”) : Error Msg: ” __FUNCTION__ ” requires ” #x)

The above lines take care of your arguments 1 to 3. Adding support for 4 would require inserting a exit() call within the macro. Also, create two different macro wrappers should you require to two different argument lists (the one with the default argument can delegate to the other macro).

#define ERROR_AND_EXIT(msg, cond, errorcode) ERROR_BUILDER(msg) if (cond) exit(errorcode)
#define ERROR_AND_CONT(msg) ERROR_BUILDER(msg)

I had put up a detailed description here (warning: that's my blog -- so consider it to be a shameless plug).

dirkgently
  • 108,024
  • 16
  • 131
  • 187