C++ 无效输入上的浮点异常有什么危险?

C++ 无效输入上的浮点异常有什么危险?,c++,c,gcc,floating-point-exceptions,C++,C,Gcc,Floating Point Exceptions,我在上运行了一些,发现了一个浮点异常 这有什么危险?它从损坏的文件中读取一些长度plen,并计算foo[i%plen]。如果plen==0,则标准未定义该值,gcc抛出浮点异常。编辑:异常未被捕获(这是C),程序终止 我应该关心吗?是否存在任何可能被利用或导致其他不好事情的情况?代码的一种可能的正确行为是注意到文件已损坏并且只是存在。这与投掷FPE然后退出有什么不同 (我很惊讶,我没有发现这方面的问题,因为这对我来说似乎非常基本。)抛出异常,使您能够在意外事件发生后将系统恢复到定义良好的状态 抛

我在上运行了一些,发现了一个浮点异常

这有什么危险?它从损坏的文件中读取一些长度
plen
,并计算
foo[i%plen]
。如果
plen==0
,则标准未定义该值,gcc抛出浮点异常。编辑:异常未被捕获(这是C),程序终止

我应该关心吗?是否存在任何可能被利用或导致其他不好事情的情况?代码的一种可能的正确行为是注意到文件已损坏并且只是存在。这与投掷FPE然后退出有什么不同


(我很惊讶,我没有发现这方面的问题,因为这对我来说似乎非常基本。)

抛出异常,使您能够在意外事件发生后将系统恢复到定义良好的状态

抛出的异常不会将系统恢复到定义良好的状态。这是你的责任。任何利用漏洞的行为都是基于您的操作方式,而不是基于抛出的异常本身

Regarding "Is there any scenario where this could be exploited or 
cause other bad things? "
从异常中恢复完全取决于引发异常的上下文。如果某些计算引发了异常,则需要继续计算,然后最好停止系统

但是,如果您的异常是针对可以忽略或可以提供其他默认选项的内容而抛出的,那么您肯定可以继续

例如:-

假设我正在使用boost程序选项阅读.ini。由于.ini文件中缺少一些变量,出现了一些异常。在这种情况下,我可以通过为该变量提供一些合适的默认值来从异常中恢复

如果
plen==0
,则该值未被标准定义

没错。这意味着,编译器可以自由地假设它不会发生。例如,这段代码

int foo(int m, int n) {
    if(n == 0) return m % n;
    return 0;
}
编译为

foo:                                    # @foo
    xorl    %eax, %eax
    ret
在我的机器(英特尔x86)上通过
clang-std=c99-S-O2
。假设从不输入
if
分支,并且
foo
无条件返回0。没有FPE,没有碰撞。(不幸的是,我找不到类似的关于
gcc
的小例子。)

。。。gcc抛出一个浮点异常

不完全是。如果代码试图除以零,这就是您的CPU。但是,如上所述,根本不能保证生成这样的代码

我怀疑GCC在这里定义了什么(并且在文档中找不到任何指示)

我应该在乎吗?是否存在任何可能被利用或导致其他不好的情况?代码的一种可能的正确行为是注意到文件已损坏并且只是存在。这与投掷FPE然后退出有什么不同

你应该关心。如果运气不好,您的程序可能会继续使用错误的输入文件,请参见上文


在我看来,错误消息“无效输入文件”比“浮点异常”要好得多。前者告诉我(作为最终用户)出了什么问题,后者只告诉我软件中有一个bug(我会这样认为)。那么,“系统”/“机器”怎么可能处于任何可能被利用的定义错误的状态呢?或者可以想象到任何其他状态在某种程度上是不好的?“代码的一种可能的正确行为是注意到文件已损坏并且只是存在。这与抛出FPE然后退出有什么不同?”因为这是由损坏的文件引起的,所以我们可以假设,合理的恢复既不可能,也不需要。那么,FPE比接住并离开更糟糕吗?(除了提供更具描述性的消息外)如果引发异常并且从未捕获到,那么它将终止您的程序,而不会让用户知道发生了什么错误。因此,您最好捕获该异常,然后显示一些有意义的消息。谢谢!所以没有危险,只是方便了用户?