我有函数取一个变量和NULL终止使用省略号指针参数列表。我知道可变长度模板参数列表。它是关于遗留代码。下面的两个调用将导致不确定的行为,因为终止由va_arg的解释为Serializable *?什么是两个电话之间的区别是什么?
void serialize(Serializable* first, ...) {
va_list vl;
va_start(vl, first);
while(1)
{
Serializable* arg = va_arg(vl, Serializable*);
if(arg == NULL)
break;
/* serialize arg here */
}
}
serialize(obj1, obj2, obj3, NULL);
serialize(obj1, obj2, obj3, nullptr);
不,我不这么认为。
如果
ap
(促销)之后的下一个参数的类型与T
兼容的行为是不确定的,除非:
- 一种类型是一个带符号的整数类型,其他类型是相应的无符号整数类型,并且该值是在两种类型的可表示;要么
- 一种类型是指针
void
,而另一个是一个指向字符类型(char
,signed char
,或unsigned char
)。
(这非常紧密地匹配实际C11措词;记住,va_arg
由C,不C ++定义。)
现在,C11的“兼容型”的定义是由another cppreference,它告诉我们,你的NULL
有与Serializable*
兼容的类型,而指向型NULL
将不得不与Serializable
兼容总结。
现在,NULL
has an implementation-defined type所以你可以不知道它是什么,但肯定不会是一个与Serializable
兼容,除非这简直是void
或int
一个类型别名,你会得到幸运。
随着nullptr
you get void*
,但再看看上面。