【发布时间】:2018-02-05 13:38:25
【问题描述】:
考虑下面的代码 sn-ps
constexpr int divide( int x, int y)
{
return (x/y);
}
constexpr int div_by_zero( int x)
{
return (x/0);
}
案例 1:
int x = divide(10,0);
这会成功编译(使用 gcc 和 clang)但会产生以下运行时错误。
浮点异常(核心转储)
案例 2:
int y = div_by_zero(10);
这会导致编译器错误,
(g++ -std=c++17) 除以零不是常量表达式
注意:即使在这种情况下,clang 也不会抛出错误
还有编译器警告:
(clang++ -std=c++17),除以零是未定义的 [-W除零]
(g++ -std=c++17),除以零[-Wdiv-by-zero]
对于案例 1,为什么在编译期间即使第二个参数的值已知(即零),编译器也不报错?
例如here 除法(10,2);生成下面的汇编代码
mov rbp, rsp
sub rsp, 16
mov DWORD PTR [rbp-4], 5
除法(10,0);生成下面的汇编代码
mov esi, 0
mov edi, 10
call divide(int, int)
当输入为零时调用 divide()。当非零值是函数的输入时,在编译时也会评估相同的值。如果编译器能够找出并调用方法而不是评估,为什么不能抛出错误?
【问题讨论】:
标签: c++ c++11 c++14 constexpr c++17