C 为什么在for循环中声明va_列表?
以下代码来自better字符串库标题。 在查看define宏时,我注意到va_list、va_start和va_end都在for循环中使用 想知道为什么这是必要的吗 顺便说一下,我已经研究了bvcformata函数,它不修改bstrmp_arglistC 为什么在for循环中声明va_列表?,c,C,以下代码来自better字符串库标题。 在查看define宏时,我注意到va_list、va_start和va_end都在for循环中使用 想知道为什么这是必要的吗 顺便说一下,我已经研究了bvcformata函数,它不修改bstrmp_arglist #define bvformata(ret, b, fmt, lastarg) { \ bstring bstrtmp_b = (b); \ const char * bstrtmp_fmt = (fmt); \
#define bvformata(ret, b, fmt, lastarg) { \
bstring bstrtmp_b = (b); \
const char * bstrtmp_fmt = (fmt); \
int bstrtmp_r = BSTR_ERR, bstrtmp_sz = 16; \
for (;;) { \
va_list bstrtmp_arglist; \
va_start (bstrtmp_arglist, lastarg); \
bstrtmp_r = bvcformata (bstrtmp_b, bstrtmp_sz, bstrtmp_fmt, bstrtmp_arglist); \
va_end (bstrtmp_arglist); \
if (bstrtmp_r >= 0) { /* Everything went ok */ \
bstrtmp_r = BSTR_OK; \
break; \
} else if (-bstrtmp_r <= bstrtmp_sz) { /* A real error? */ \
bstrtmp_r = BSTR_ERR; \
break; \
} \
bstrtmp_sz = -bstrtmp_r; /* Doubled or target size */ \
} \
ret = bstrtmp_r; \
}
#endif
#定义bvformata(ret、b、fmt、lastarg){\
bstring bstrtmp_b=(b)\
常量字符*bstrtmp_fmt=(fmt)\
int bstrtmp_r=BSTR_ERR,bstrtmp_sz=16\
对于(;){\
va_列表bstrtmp_参数列表\
va_开始(bstrtmp_参数列表,最后参数)\
bstrtmp_r=bvcformata(bstrtmp_b、bstrtmp_sz、bstrtmp_fmt、bstrtmp_arglist)\
va_端(bstrtmp_参数列表)\
如果(bstrtmp_r>=0){/*一切正常*/\
bstrtmp_r=BSTR_OK\
中断\
}else if(-bstrtmp\u r别介意愚蠢的我。我只是注意到for循环中存在“break”。通过“moving”va_list和va_end out将产生内存泄漏。您可以将va_list
声明移到循环之外。但是va_start
和va_end
必须留在循环中,这样对bvcformata()
的每次调用都将从头开始处理变量参数
#define bvformata(ret, b, fmt, lastarg) { \
bstring bstrtmp_b = (b); \
const char * bstrtmp_fmt = (fmt); \
int bstrtmp_r = BSTR_ERR, bstrtmp_sz = 16; \
va_list bstrtmp_arglist; \
for (;;) { \
va_start (bstrtmp_arglist, lastarg); \
bstrtmp_r = bvcformata (bstrtmp_b, bstrtmp_sz, bstrtmp_fmt, bstrtmp_arglist); \
va_end (bstrtmp_arglist); \
if (bstrtmp_r >= 0) { /* Everything went ok */ \
bstrtmp_r = BSTR_OK; \
break; \
} else if (-bstrtmp_r <= bstrtmp_sz) { /* A real error? */ \
bstrtmp_r = BSTR_ERR; \
break; \
} \
bstrtmp_sz = -bstrtmp_r; /* Doubled or target size */ \
} \
ret = bstrtmp_r; \
}
#endif
#定义bvformata(ret、b、fmt、lastarg){\
bstring bstrtmp_b=(b)\
常量字符*bstrtmp_fmt=(fmt)\
int bstrtmp_r=BSTR_ERR,bstrtmp_sz=16\
va_列表bstrtmp_参数列表\
对于(;){\
va_开始(bstrtmp_参数列表,最后参数)\
bstrtmp_r=bvcformata(bstrtmp_b、bstrtmp_sz、bstrtmp_fmt、bstrtmp_arglist)\
va_端(bstrtmp_参数列表)\
如果(bstrtmp_r>=0){/*一切正常*/\
bstrtmp_r=BSTR_OK\
中断\
}else if(-bstrtmp\u r)你为什么这么认为?你更新的代码在循环外调用va\u end
。如果va\u list
是指针,我认为不能保证va\u arg()
不会取消指针引用并修改内容。如果我在公司代码中看到这种宏,我会强迫作者在黑板上写1000次“我再也不会写这样的东西了”
#define bvformata(ret, b, fmt, lastarg) { \
bstring bstrtmp_b = (b); \
const char * bstrtmp_fmt = (fmt); \
int bstrtmp_r = BSTR_ERR, bstrtmp_sz = 16; \
va_list bstrtmp_arglist; \
for (;;) { \
va_start (bstrtmp_arglist, lastarg); \
bstrtmp_r = bvcformata (bstrtmp_b, bstrtmp_sz, bstrtmp_fmt, bstrtmp_arglist); \
va_end (bstrtmp_arglist); \
if (bstrtmp_r >= 0) { /* Everything went ok */ \
bstrtmp_r = BSTR_OK; \
break; \
} else if (-bstrtmp_r <= bstrtmp_sz) { /* A real error? */ \
bstrtmp_r = BSTR_ERR; \
break; \
} \
bstrtmp_sz = -bstrtmp_r; /* Doubled or target size */ \
} \
ret = bstrtmp_r; \
}
#endif