C:浮动变为'nan'值

时间:2015-01-24 19:04:43

标签: c

我在一个更大的程序中有一个内部函数,它以某种方式将浮点值更改为" nan"当我预计它为零。我已将函数修剪为最简单的形式,没有参数:

static void func(void)
{
    int a = 1;
    float x = 0.0f;
    float v = 0.0f;
    printf("x(%f), ", x);
    x += (float)a * v;
    printf("x(%f), ", x);
    printf("(int)x: %d, ", (int)x);
}

这给出了输出:

x(0.000000), x(nan), (int)x: -2147483648

如果我删除变量a并对值(1)进行硬编码,则nan值消失。同样,如果我删除行x += (float)a * v;,则所有内容都按预期打印(全为零)。

令人沮丧的是,我无法通过创建一个新程序并在main()中抛弃它来重现这一点。当我尝试这个时,程序运行完美并输出:

x(0.000000), x(0.000000), (int)x: 0

从实际程序中的函数中反汇编:

00000029 <_func>:
  29: 55                    push   %ebp
  2a: 89 e5                 mov    %esp,%ebp
  2c: 83 ec 38              sub    $0x38,%esp
  2f: c7 45 f4 01 00 00 00  movl   $0x1,-0xc(%ebp)
  36: a1 18 00 00 00        mov    0x18,%eax
  3b: 89 45 f0              mov    %eax,-0x10(%ebp)
  3e: a1 18 00 00 00        mov    0x18,%eax
  43: 89 45 ec              mov    %eax,-0x14(%ebp)
  46: d9 45 f0              flds   -0x10(%ebp)
  49: dd 5c 24 04           fstpl  0x4(%esp)
  4d: c7 04 24 00 00 00 00  movl   $0x0,(%esp)
  54: e8 a7 ff ff ff        call   0 <_printf>
  59: d9 45 f0              flds   -0x10(%ebp)
  5c: db 45 f4              fildl  -0xc(%ebp)
  5f: d9 5d e4              fstps  -0x1c(%ebp)
  62: d9 45 e4              flds   -0x1c(%ebp)
  65: d9 45 ec              flds   -0x14(%ebp)
  68: de c9                 fmulp  %st,%st(1)
  6a: de c1                 faddp  %st,%st(1)
  6c: d9 5d f0              fstps  -0x10(%ebp)
  6f: d9 45 f0              flds   -0x10(%ebp)
  72: dd 5c 24 04           fstpl  0x4(%esp)
  76: c7 04 24 00 00 00 00  movl   $0x0,(%esp)
  7d: e8 7e ff ff ff        call   0 <_printf>
  82: d9 45 f0              flds   -0x10(%ebp)
  85: d9 7d e2              fnstcw -0x1e(%ebp)
  88: 0f b7 45 e2           movzwl -0x1e(%ebp),%eax
  8c: b4 0c                 mov    $0xc,%ah
  8e: 66 89 45 e0           mov    %ax,-0x20(%ebp)
  92: d9 6d e0              fldcw  -0x20(%ebp)
  95: db 5d dc              fistpl -0x24(%ebp)
  98: d9 6d e2              fldcw  -0x1e(%ebp)
  9b: 8b 45 dc              mov    -0x24(%ebp),%eax
  9e: 89 44 24 04           mov    %eax,0x4(%esp)
  a2: c7 04 24 08 00 00 00  movl   $0x8,(%esp)
  a9: e8 52 ff ff ff        call   0 <_printf>
  ae: c9                    leave  
  af: c3                    ret    

从独立功能(作为main())进行反汇编:

00000000 <_main>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   83 e4 f0                and    $0xfffffff0,%esp
   6:   83 ec 30                sub    $0x30,%esp
   9:   e8 00 00 00 00          call   e <_main+0xe>
   e:   c7 44 24 2c 01 00 00    movl   $0x1,0x2c(%esp)
  15:   00 
  16:   a1 18 00 00 00          mov    0x18,%eax
  1b:   89 44 24 28             mov    %eax,0x28(%esp)
  1f:   a1 18 00 00 00          mov    0x18,%eax
  24:   89 44 24 24             mov    %eax,0x24(%esp)
  28:   d9 44 24 28             flds   0x28(%esp)
  2c:   dd 5c 24 04             fstpl  0x4(%esp)
  30:   c7 04 24 00 00 00 00    movl   $0x0,(%esp)
  37:   e8 00 00 00 00          call   3c <_main+0x3c>
  3c:   db 44 24 2c             fildl  0x2c(%esp)
  40:   d8 4c 24 24             fmuls  0x24(%esp)
  44:   d9 44 24 28             flds   0x28(%esp)
  48:   de c1                   faddp  %st,%st(1)
  4a:   d9 5c 24 28             fstps  0x28(%esp)
  4e:   d9 44 24 28             flds   0x28(%esp)
  52:   dd 5c 24 04             fstpl  0x4(%esp)
  56:   c7 04 24 00 00 00 00    movl   $0x0,(%esp)
  5d:   e8 00 00 00 00          call   62 <_main+0x62>
  62:   d9 44 24 28             flds   0x28(%esp)
  66:   d9 7c 24 1e             fnstcw 0x1e(%esp)
  6a:   0f b7 44 24 1e          movzwl 0x1e(%esp),%eax
  6f:   b4 0c                   mov    $0xc,%ah
  71:   66 89 44 24 1c          mov    %ax,0x1c(%esp)
  76:   d9 6c 24 1c             fldcw  0x1c(%esp)
  7a:   db 5c 24 18             fistpl 0x18(%esp)
  7e:   d9 6c 24 1e             fldcw  0x1e(%esp)
  82:   8b 44 24 18             mov    0x18(%esp),%eax
  86:   89 44 24 04             mov    %eax,0x4(%esp)
  8a:   c7 04 24 08 00 00 00    movl   $0x8,(%esp)
  91:   e8 00 00 00 00          call   96 <_main+0x96>
  96:   b8 00 00 00 00          mov    $0x0,%eax
  9b:   c9                      leave  
  9c:   c3                      ret    
  9d:   90                      nop
  9e:   90                      nop
  9f:   90                      nop

1 个答案:

答案 0 :(得分:0)

此问题通常是未定义行为的结果。在这个特定的例子中,有一个隐式函数声明(一个头文件没有包含在程序的其他地方)导致UB,并导致了这个错误。