C ++中对int的文字赋值是否会引发异常?

时间:2012-05-16 16:03:05

标签: c++ exception try-catch

给出如下代码:

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

由于简单的赋值,系统是否可能抛出异常?

[编辑:对于那些说“没有例外不能发生”的人,你能指出我的C ++标准部分的方向吗?我找不到它。]

5 个答案:

答案 0 :(得分:7)

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

  

执行 throw-expression 的代码被称为“抛出异常;”[...]

反过来看,不执行throw-expression的代码不会抛出异常。]

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

编辑:就任务而言,有很多方法可以抛出。显然,投入任务操作员本身就可以做到,但还有相当多的其他人。例如,如果源类型与目标类型不匹配,则可能通过源中的强制转换操作符或目标中的构造函数进行转换 - 其中任何一个都可能抛出。

答案 1 :(得分:6)

有很多东西看起来像是可以抛出这样或那样的任务:

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的新版本)

答案 2 :(得分:3)

如果您担心将0(类型为int)分配给。{ int,该标准的§5.17非常准确地指出了语义 赋值操作,并且不存在可能发生异常的情况。 如果您担心将任意表达式分配给int, §5.17说“表达式被隐含地转换为 cv-unqualified类型的左操作数。“取决于实际类型 正确的操作数:

  • 如果它是整数类型,如果实际值不能用int表示,则结果是实现定义的(C标准更明确:它必须导致{{1使用实现定义的值,或者您将获得实现定义的信号)

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

  • 如果是用户定义的类型,则将调用用户定义的转换运算符。哪个可以抛出异常。

如果您担心分配其他类型:每组 非类类型,有一个像上面这样的规则列表,但是唯一的 可能的异常将是类型转换的结果。上课 类型,将使用int。哪个可以抛出异常, 取决于其中的内容。

答案 3 :(得分:2)

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

答案 4 :(得分:0)

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

如果它是一个更复杂的东西,比如矢量,那么它可能会因为多种原因而抛出(例如分配失败或从辅助线程更改)。