c - 常量表达式的数学函数是否在编译时预先计算?

标签 c math compile-time

为了方便和连贯,我倾向于使用常量表达式的数学函数(即 log(x)/log(2) 而不是 log(x)/0.3...)。由于这些函数实际上并不是语言本身的一部分,它们也没有在 math.h 中定义(仅声明),常量函数会在编译时预先计算,还是会被浪费地计算在运行时?

最佳答案

这取决于编译器和优化标志。正如@AndrewyT 指出的那样,GCC 能够通过属性指定哪些函数是常量和纯函数,在这种情况下答案是肯定的,它将内联结果,您可以轻松检查:

$ cat constant_call_opt.c 
#include <math.h>

float foo() {
        return log(2);
}

$ gcc -c constant_call_opt.c -S

$ cat constant_call_opt.s 
        .file   "constant_call_opt.c"
        .text
.globl foo
        .type   foo, @function
foo:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $4, %esp
        movl    $0x3f317218, %eax
        movl    %eax, -4(%ebp)
        flds    -4(%ebp)
        leave
        ret
        .size   foo, .-foo
        .ident  "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3"
        .section        .note.GNU-stack,"",@progbits

那里没有函数调用,只是加载一个常量(0x3f317218 == 0.69314718246459961 == log(2))

虽然我现在手头没有任何其他编译器可以尝试,但我认为您可以期望所有主要的 C 编译器都有相同的行为,因为这是一个微不足道的优化。

关于c - 常量表达式的数学函数是否在编译时预先计算?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2049412/

相关文章:

java - Java 中的 ECEF 到 lla (lat,lon,alt)

java - 对数螺旋

c++ - {fmt} : always compile-time check format string in function

c# - 在编译时确保互斥接口(interface)?

java - 静态数据结构

c - 如何通过命名管道(fifo)传输结构的内容?

更改返回地址以指向 shellcode

c# - 将大数字(或字符串)压缩为小值

c - 如何在内存中存储任意大的整数值?

c - 如何解决此转换为不同大小警告的指针?