我正在尝试为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;
}
答案 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)
以确保编译器将宏视为单个语句。
希望它有所帮助。