当的计算铸造执行?

时间:2019-02-02 19:00:58

标签: c

我从来没有真正理解发生在当涉及到铸什么。 我以为隐式转换发生在编译时(如果我错了指正),但对于这样的:

int i = 0;

double d = sqrt((double)i);

这是否会发生在编译时/运行时间?

2 个答案:

答案 0 :(得分:6)

没关系,也没有指定(检查C11标准n1570)。请注意as-if规则。它实际上取决于你的编译器是如何optimizing

如果仅将代码放入某个main函数中,并在启用优化的情况下对其进行编译,则GCC编译器将为您提供一个空程序(因为所有计算都可以在编译时完成,并且因为d不用于可观察到的副作用。

如果您有GCC编译功能使用您的代码gcc -O3 -S -fverbose-asm,并期待产生*.s汇编文件中。你会感到惊讶。

特别是在Linux / Debian / x86-64上的GCC 8中,

的编译
// file dvep.c
#include <math.h>
int
main (void)
{
  int i = 0;
  double d = sqrt ((double) i);
  return 0;
}

使用gcc -O3 -S -fverbose-asm dvep.c命令产生dvep.s的文件,其main功能降低为:

    .globl  main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
# dvep.c:9: }
    xorl    %eax, %eax  #
    ret 
    .cfi_endproc

然后您看到main内的运行时没有浮点运算

答案 1 :(得分:6)

这取决于优化和体系结构。例如,带有-O3的GCC将完全省略对sqrt的某些值调用,如here所示。

如果在编译时不知道该变量(即,是从文件还是从用户输入中读取),则无法用双精度值sqrt实际调用i 。在x86上,这需要类似CVTSI2SD(将Doubleword Integer转换为标量双精度浮点值)之类的指令,如here所示。编译器产生的指令在编译时间,但运行指令(明显)在运行时发生。