int 的文本赋值是否可以C++引发异常

Can a literal assignment to int in C++ throw an exception?

本文关键字:C++ 异常 文本 赋值 是否 int      更新时间:2023-10-16

给定如下代码:

void f()
{
   int i;
   i = 0;
}

系统是否有可能由于简单的分配而引发异常?

[编辑:对于那些说"不例外不会发生"的人,你能指出我C++标准中说这句话的部分的方向吗?我找不到它。

虽然你可能很难在标准中找到它的保证,但一个简单的经验法则是,任何在 C 中合法的东西都可能无法抛出。[编辑:据我所知,最接近这种直接声明的是§15/2,它说:

执行抛出

表达式的代码被称为">抛出异常";[...]

反过来看,不执行抛出表达式的代码不会引发异常。

抛掷基本上仅限于两种可能性:第一种是调用 UB。第二种是对C++执行一些独特的操作,例如分配给重载operator =的用户定义类型,或使用new表达式。

编辑:就作业而言,它可以通过多种方式抛出。显然,引入赋值运算符本身就可以做到这一点,但还有相当多的其他运算符。例如,如果源类型与目标类型不匹配,则可以通过源中的强制转换运算符或目标中的构造函数获得转换 - 其中任何一个都可能引发。

有很多

东西看起来像作业,可以以一种或另一种方式抛出:

int operator"" _t(const char *) { throw 0; } // C++11 user defined literal 
struct foo {
  foo(int) { throw 0; }
  operator int() { throw 0; }
  foo& operator=(int) { throw 0; }
};
int main() {
  int i;
  i = 0; // can't throw
  i = 0_t; // User defined literal throws
  foo f = 0; // Constructor throws
  i = f; // conversion operator throws
  f = 0; // assignment throws
  f = f; // both conversion and assignment would like to throw
}

(包括C++11的新版(

如果您担心将0(类型为 int(断言为 int,该标准的§5.17非常准确地规定了赋值操作,并且不存在可能发生异常的情况。如果您担心将任意表达式分配给int,§5.17 说"表达式被隐式转换为CV-不合格类型的左操作数。 取决于实际类型正确的操作数:

  • 如果是整型,如果实际值不能用int表示,则结果是实现定义的(C标准更明确:它必须产生具有实现定义值的int,否则您将获得实现定义的信号(

  • 如果是浮点值,则结果是未定义的行为,如果截断为零后的值无法在int中表示,则行为未定义(因此您可能会遇到异常(

  • 如果是用户定义类型,则将调用用户定义的转换运算符。 这可能会引发异常。

如果您担心分配其他类型:对于每组非类类型,有一个类似于上面的规则列表,但唯一的可能的异常将是类型转换的结果。 对于类类型,将使用operator=。 这可能会引发异常,取决于其中的内容。

它只能在一种情况下引发异常:当这两种类型的重载operator=()抛出时;同样,当需要转换时,转换构造函数或operator T()也可以抛出。这取决于确切的实现 - 要了解它是否会抛出,请在您正在使用的库文档中查找有关它的信息。

如果它只是一个int,那么不 - 它不会抛出。

如果它是更复杂的东西,例如向量,那么它可能由于多种原因(例如分配失败或从辅助线程更改(而抛出。