使用空指针

时间:2015-12-23 11:48:39

标签: c++ variadic-functions nullptr

我们有很多遗留的C ++代码,其函数带有可变数量的指针参数。在每种情况下,空指针都表示参数列表的结尾。在遗留代码中,文字0用于空指针。因为C ++变量参数列表函数没有对变量参数的类型进行原型化,所以终止参数作为整数0传递。在某些64位环境中,整数是32位而指针是64位。是否存在被调用函数将看到非零指针的风险(即,低位32位字为零,但高位32位包含垃圾)?将所有0个参数更改为nullptr可能是正确的方法。我的问题是:这有必要吗?即如果我们不这样做,是否存在真正的错误风险?

class mytype;  
void foo(mytype*, ...); 

mytype a, b, c;
foo(&a, &b, &c, 0);  //is this ok ?
foo(&a, &b, &c, nullptr); //or must it be so ?

3 个答案:

答案 0 :(得分:3)

您已经对您的用户进行了教育。如果将每个参数解压缩为va_arg(ap, mytype*),则用户应使用(mytype*)(0)而不是0向列表末尾发出信号。您现有的代码始终具有未定义的行为。即使nullptr也不合适,因为当它是无类型参数时,它将作为void*传递,因此正确的参数再次为static_cast<mytype*>(nullptr)

如果您要求针对未定义的行为进行特定于平台的制裁,请咨询您的供应商。

答案 1 :(得分:0)

(部分)解决方案是使用运算符重载:

void saferfoo(mytype* a0, mytype* a1, ..., mytype* an, int zero) {
   foo(a0, a1, ..., an, static_cast<mytype*>(nullptr));
}

这里... 不是来自C ++语言的省略号,而是我们人类语言的省略号。

您必须为代码中存在的每个参数定义函数,您还必须重新编译相关代码。由于只有过去/现在误用foo受影响,你可以这样做并使用棒球棒来处理未来foo的误用。

答案 2 :(得分:-3)

在我看来,使用0是一种非便携式解决方案。根据编译器的不同,它可以转换为数组元素的数据类型,也可以转换为int(0)。

因此,我个人建议在这种情况下始终使用NULL。