【问题标题】:Why does this code cause a Floating point exception - SIGFPE为什么此代码会导致浮点异常 - SIGFPE
【发布时间】:2012-09-25 21:53:03
【问题描述】:

使用 gcc 4.7:

$ gcc --version
gcc (GCC) 4.7.0 20120505 (prerelease)

代码清单(test.c):

#include <stdint.h>

struct test {
    int before;

    char start[0];
    unsigned int v1;
    unsigned int v2;
    unsigned int v3;
    char end[0];

    int after;
};

int main(int argc, char **argv)
{
  int x, y;

  x = ((uintptr_t)(&((struct test*)0)->end)) - ((uintptr_t)(&((struct test*)0)->start));
  y = ((&((struct test*)0)->end)) - ((&((struct test*)0)->start));

  return x + y;
}

编译并执行

$ gcc -Wall -o test test.c && ./test
Floating point exception

SIGFPE 是由第二个赋值 (y = ...) 引起的。在装配清单中,这条线上有划分吗?请注意,x= 和 y= 之间的唯一区别是转换为 (uintptr_t)。

【问题讨论】:

  • GCC 浏览器输出:preview.tinyurl.com/8ah2fa7
  • char start[0]; 表示您超出了标准定义的范围。除此之外会发生什么,真的那么有趣吗?

标签: c exception compiler-optimization gcc4


【解决方案1】:

忽略由于违反标准中的约束而导致的未定义行为,gcc 在这里所做的是计算两个指向 char[0] - &amp;(((struct test*)0)-&gt;start)&amp;(((struct test*)0)-&gt;end) 的指针之间的差异,并将该差异除以 a 的大小char[0],当然是0,所以你得到一个除以0。

【讨论】:

  • 由于 UNIX 中的历史原因,整数除以 0 会产生浮点异常(SIGFPE 信号)
  • 这是 UNIX(及其衍生产品)的专长吗?我以为这是 x86 的东西。
  • 问得好,我知道 UNIX 上的 x86 就是这种情况,但我不确定其他系统是否也是这种情况。
  • 如果有人确实知道,也请 ping @ouah。我肯定有兴趣知道。
  • 在 Linux armv6l 上用0 测试整数除法,它也给出了一个浮点异常。
猜你喜欢
  • 2013-05-31
  • 1970-01-01
  • 1970-01-01
  • 2020-10-01
  • 2016-06-30
  • 2023-04-02
  • 1970-01-01
  • 2011-06-25
相关资源
最近更新 更多