带有可变参数的 C 宏 - "incompatible pointer type"

C Macro with variable args - "incompatible pointer type"

我正在尝试为 vsnprintf 创建一个包装器宏。如果发生截断,我希望它最终能够记录行号,因此我将其设为宏,以便我可以使用 __LINE __ 宏。但是编译器不喜欢我目前所拥有的:

foo.c: In function ‘main’:
foo.c:35:44: warning: passing argument 4 of ‘vsnprintf’ from incompatible pointer type
MYPRINT(buffer,&result,LENGTH,"hello %s","world");
^
foo.c:27:52: note: in definition of macro ‘MYPRINT’
result = vsnprintf(destination,size,format, ## args );  \
^
In file included from foo.c:10:0:
/usr/include/stdio.h:390:12: note: expected ‘struct __va_list_tag *’ but argument is of type ‘char *’
extern int vsnprintf (char *__restrict __s, size_t __maxlen,

我的代码如下。我不确定如何解决它。也许我需要用括号括起来?

#define LENGTH (512)

#define MYPRINT(destination,result_ptr,size,format,args...) \
  {                                                         \
    int result;                                             \
    result = vsnprintf(destination,size,format, ## args );  \
    *result_ptr = result;                                   \
  }

int main (int argc, char **argv)
{
  int result;
  char buffer[LENGTH];
  MYPRINT(buffer,&result,LENGTH,"hello %s","world");
  fprintf(stderr,"%s\n",buffer);
  return 0;
}

你真的不需要 vsnprintf()。您应该使用 snprintf()__VA_ARGS__,自 C99 以来,它们将与可变参数宏一起使用。 vsnprintf() 最好与可变函数一起使用,而不是与可变宏一起使用。

这是您的代码的一个稍微更正的版本。

#include <stdio.h>
#include <stdarg.h>

#define LENGTH 512

#define MYPRINT(destination,res,size,format, ...) \
  do {                                                      \
    int m_res;                                             \
    m_res = snprintf(destination,size,format, __VA_ARGS__ );  \
    res = m_res;                                   \
  } while (0)

int main (int argc, char **argv)
{
  int result;
  char buffer[LENGTH];
  MYPRINT(buffer,result,LENGTH,"hello %s","world");
  fprintf(stderr,"%s\n",buffer);
  return 0;
}

请注意,由于 MYPRINT 是一个宏(而不是函数),您不需要将指针传递给变量 result。您实际上传递的是变量本身的 name。就像你现在所做的那样,你会在 main 中声明的 result 和宏块中声明的 result 之间发生冲突。

我添加了习语 do {} while(0) 以确保编译器将宏视为单个语句。

希望对您有所帮助。