fea*_*ool 1 c variadic-functions
我有一个varargs样式的函数,我想拆分为va_list样式的子函数。原始功能:
void container_append(container_t *c, element_t *element, ...) {
element_t *e;
va_list ap;
va_start(ap, element);
while((e = va_arg(ap, element_t *)) != NULL) {
container_append_aux(c, e);
}
va_end(ap);
}
Run Code Online (Sandbox Code Playgroud)
请注意,调用者必须以NULL终止元素列表,但这不会引起任何问题。重构:
void container_append(container_t *c, element_t *element, ...) {
va_list ap;
va_start(ap, element);
container_vappend(c, ap);
va_end(ap);
}
void container_vappend(container_t *c, va_list ap) {
element_t *e;
while ((e = va_arg(ap, element_t *)) != NULL) {
container_append_aux(c, e);
}
}
Run Code Online (Sandbox Code Playgroud)
但是,当我这样称呼它时:
container_append(c, NULL);
Run Code Online (Sandbox Code Playgroud)
...内container_vappend()的呼叫传va_arg()回非NULL的值。
这是一个更复杂的函数的抄写,但是除非有任何错别字,否则我在设置和使用va_listand时错过了什么va_arg()吗?
container_append(c, one or more arguments, NULL);是潜在的不确定行为(UB)。
container_append()期望一个element_t *element并且NULL可能很简单0。
NULL扩展为实现定义的空指针常量...值为0的整数常量表达式或转换为类型的表达式
void *称为空指针常量。
NULL 甚至没有指定与指针相同的大小。
va_arg(ap, element_t *) 然后是UB。
为了拨打更安全的电话,请使用 container_append(c, args, (element_t *) NULL);