3

如果您违反对模板类型的任何要求、提供错误的函数参数或任何其他违约行为,标准库通常会允许未定义的行为。在用户库中允许这样做是否被认为是一种好习惯?什么时候这样做是公平的?

operator[]考虑为容器编写一个:

template <typename t>
T& container<T>::operator[](int i)
{
  return internal_array[i];
}

如果i索引超出了 的范围internal_array,我们会遇到未定义的行为。我们应该允许这种情况发生还是进行边界检查并抛出异常?

另一个例子是一个接受int参数但只允许受限域的函数:

int foo(int x)
{
  if (x > 0 && x <= 10) {
    return x;
  }
}

如果x不在域内,则执行将在没有return语句的情况下到达函数的末尾 - 这会产生未定义的行为。

图书馆开发人员是否应该因为允许这样做而感到难过?

4

2 回答 2

3

什么时候故意引起未定义的行为是公平的?

假设您是从库实现者的角度提出这个问题:每当您警告客户未能遵守给定函数的先决条件会导致未定义行为,并且您的客户违反了这些先决条件。

C++11 标准库定义了很多这样的函数:想想序列集合的下标运算符。

另一方面,如果您是从应用程序程序员的角度来问这个问题,答案当然是“从不”,除非您正在编写依赖于编译器的某些文档化扩展和/或某些您的操作系统的功能(但是您是否仍在“谈论 C++”是有争议的)。

图书馆开发人员是否应该因为允许这样做而感到难过?

如果是这样的话,先生。斯捷潘诺夫现在应该感觉很糟糕。不,这还不错,这仅取决于您的库是为最大效率还是为最大安全而设计的——中间有很多细微差别。

于 2013-02-13T23:03:47.490 回答
1

这一切都归结为文档。

直觉上你不会期望[]做任何边界检查,但你也可以为at你的容器提供一个抛出异常的方法(是的,就像编写std. 当然,您可以抛出异常,但要记录此行为。

第二个是公平竞争,只要您清楚地记录如果使用错误参数调用函数并且您有充分的理由这样做(红色亮起),则行为未定义。如果您正在设计一个性能关键库,您不希望检查输入的开销。如果不是,则抛出异常。

于 2013-02-13T23:06:28.117 回答