C宏与变量args - "不兼容的指针类型"

时间:2015-08-25 19:10:27

标签: c macros

我正在尝试为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,

我的代码如下。我不确定如何解决它。也许我需要在parens中包装一些东西?

#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;
}

1 个答案:

答案 0 :(得分:0)

你真的不需要vsnprintf()。自C99起,您应该使用snprintf()__VA_ARGS__与可变参数宏一起使用。 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。您实际上正在传递变量本身的名称。正如您现在所做的那样,您将在main中声明的result与宏体块中声明的result之间发生冲突。

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

希望它有所帮助。