API上函数参数的一致性更改

Const-correctness of function parameters on API changes

本文关键字:一致性 参数 函数 API      更新时间:2023-10-16

假设我使用的是一个实现函数foo的库,我的代码可能如下所示:

void foo(const int &) { }
int main() {
    int x = 1;
    foo(x);
    std::cout << (1/x) << std::endl;
}

一切都很好。但现在假设foo由于某种原因被修改或过载。现在我们得到的可能是这样的东西:

void foo(int & x) {
    x--;
}
void foo(const int &) {}
int main() {
    int x = 1;
    foo(x);
    std::cout << (1/x) << std::endl;
}

砰。程序突然中断。这是因为我们实际上想要传递的代码片段是一个常量引用,但随着API的突然变化,编译器选择了我们不想要的版本,程序意外中断。

实际上我们想要的是:

int main() {
    int x = 1;
    foo(static_cast<const int &>(x));
    std::cout << (1/x) << std::endl;
}

通过此修复,程序将重新开始工作。然而,我必须说,我在代码中没有看到过很多这样的强制转换,因为每个人似乎都相信这种类型的错误不会发生。此外,这似乎是不必要的冗长,如果有多个参数并且名称开始变长,函数调用就会变得非常混乱。

这是合理的担忧吗?我应该如何处理?

如果您更改一个接受常量引用的函数,使其不再是常量,那么您可能会破坏它。这意味着您必须检查调用该函数的每个地方,并确保它是安全的。在这种情况下,进一步使用两个同名函数,一个带const,另一个不带const肯定是一个糟糕的计划。

正确的做法是创建一个新函数,该函数使用与现有函数不同的名称来执行x--变体。

任何API供应商如果做了这样的事情,都应该受到严厉的惩罚,如果文档中有一个BIG通知,说"我们已经更改了函数foo,现在它会递减x,除非参数被强制为const",则可能会少一些暴力行为。这是人们能想象到的最糟糕的二进制中断之一(就"很难找出问题所在"而言)。