带有可变参数的 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)
以确保编译器将宏视为单个语句。
希望对您有所帮助。
我正在尝试为 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)
以确保编译器将宏视为单个语句。
希望对您有所帮助。