【发布时间】:2020-10-28 21:10:25
【问题描述】:
以下代码来自更好的字符串库头。 在查看定义宏时,我注意到 va_list、va_start 和 va_end 都在 for 循环中使用。
想知道为什么这是必要的吗?
顺便说一句,我研究了不修改 bstrmp_arglist 的函数 bvcformata。
#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
是否可以将 va_list、va_start 和 va_end 从 for 循环中“移出”?我仍然是 C 的初学者。只是想知道为什么必须在 for 循环中使用它们?
#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; \ <--------*****
va_start (bstrtmp_arglist, lastarg); \ <--------*****
for (;;) { \
bstrtmp_r = bvcformata (bstrtmp_b, bstrtmp_sz, bstrtmp_fmt, 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 */ \
} \
va_end (bstrtmp_arglist); \ <--------*****
ret = bstrtmp_r; \
}
#endif
【问题讨论】:
-
如果
va_list是一个指针,我认为不能保证va_arg()不会取消引用指针并修改其内容。 -
如果我在我们公司的代码中看到这种宏我会强迫作者在黑板上写1000遍“我再也不会写这种东西了”i.stack.imgur.com/P5Zdr.jpg
标签: c