How to convert a variable argument function to a macro?

I have a variable argument function that prints error messages in my application, the code of which is given below:

void error(char *format,...)
{   va_list args;
    printf("Error: ");
    va_start(args, format);
    vfprintf(stderr, format, args);
    va_end(args);
    printf("\n");
    abort(); 
}

This function is used under error conditions as follows:

error("invalid image width %d and image height %d in GIF file %s",wid,hei,name);

The function error()is called from different places with different arguments (variable argument function).

A functional approach works fine.

Now, if I need to convert this function to a macro, how do I do this? I tried to do it like:

#define error(format)  {va_list args;\
    printf("Error: ");\
    va_start(args, format);\
    vfprintf(stderr, format, args);\
    va_end(args);\
    printf("\n"); abort()}

But this incorrectly prints the arguments.

What is wrong with the macro definition above?

What is a fix?

+3
source share
5 answers

ISO, :

#define error(...) \    
    fprintf(stderr, "Error: ");   \
    fprintf(stderr, __VA_ARGS__); \
    fprintf(stderr, "\n"); \
    abort();

, GCC, GNU :

#define error(format, args...) \    
    fprintf(stderr, "Error: ");   \
    fprintf(stderr, format , ## args); \
    fprintf(stderr, "\n"); \
    abort();

. http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html

, (?) va_list . , , , ?

static inline void error(const char *fmt, ...) {
#define PRINT_ERROR
    va_list args;
    fprintf(stderr, "Error: "); 
    va_start(args, fmt);
    vfprintf(stderr, fmt, args);
    va_end(args);
    fprintf(stderr, "\n");
    abort();
#endif
}
+2

, . , , . __VA_ARGS__ .

?

+1

, va_list , .

( , ) ?

0

GNU, :

#define error(format,args...) do { \
  fprintf(stderr, "error: " format "\n", ##args); \
  abort(); \
} while(0)

, , .

0

, , , :

#define error(args...) (fputs("Error: ",stdout),printf(args),puts(""))

C99 :

#define error(...) (fputs("Error: ",stdout),printf(__VA_ARGS__),puts(""))

but there are some problems with using __VA_ARGS__. Fortunately, there is a GCC extension to handle this, but then you returned to using the extension for the compiler, and the mode args...became more accessible.

0
source

Source: https://habr.com/ru/post/1715986/


All Articles