Do math functions of constant expressions get pre-calculated at compile time?

后端 未结 6 1096
感动是毒
感动是毒 2020-12-06 17:10

I tend to use math functions of constant expressions for convinience and coherence (i.e log(x)/log(2) instead of log(x)/0.3...). Since these functi

相关标签:
6条回答
  • 2020-12-06 17:33

    It depends on the compiler and the optimization flags. As @AndrewyT points out, GCC has the ability to specify which functions are constant and pure via attributes, and in this case the answer is positive, it will inline the result, as you can easily check:

    $ 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
    

    no function call there, just loads a constant (0x3f317218 == 0.69314718246459961 == log(2))

    Althought I have not any other compiler at hand to try now, I think you could expect the same behaviour in all the major C compilers out there, as it's a trivial optimization.

    0 讨论(0)
  • 2020-12-06 17:33

    This happens at runtime since the code for the function only becomes available during the linking step (which happens after the compile step).

    To optimize the step, use a global variable which you initialize before you use it.

    0 讨论(0)
  • 2020-12-06 17:34

    They'll usually get calculated at runtime (see other answers for how to inline them), though I wouldn't necessarily use the word "wastefully" unless there were a lot of them and/or the code was executed lots of times.

    Rather than just put in the constant value, create a #define or const variable that expresses what the value means (PI, LOG_2, etc.) and use that instead.

    For example:

    #define LOG_2 0.30102999566
    

    This doesn't do any calculation and you can specify the value to what ever precision you desire or can manage given your environment (32 bit v 64 bit).

    0 讨论(0)
  • 2020-12-06 17:48

    Some compilers will evaluate them at compile time, but this behavior is not guaranteed (and doing so may also cause problems). You'll need to check your compiler and see what it does.

    Note that on many systems, log(2) is available from the macro M_LN2 in <math.h>.

    0 讨论(0)
  • 2020-12-06 17:50

    In case of library functions, some compiler might implement these functions as intrinsics, meaning that the compiler knows enough about the functions to replace the call with a constant at compile time. Whether it will do this depends on the compiler. In practice, I often notice that some compilers are reluctant to pre-calculate floating-point expressions at compile time, even if they don't involve any function calls.

    In general case, normally they won't and can't get calculated at compile time, assuming the compiler simply doesn't know enough about these functions to be able to calculate them at compile time. Maybe they have some prominent run-time side-effects?

    Some compilers might have non-standard compiler-dependent extensions that allow user to provide the additional information about the functions to the compiler, so that the compiler can optimize function calls better and even figure out whether a given call can be replaced with a compile-time pre-calculation. For example, GCC compiler supports such function attributes (GCC-specific extension) as const and pure. If the arguments are known at compile time, a call to function with the const attribute can be theoretically replaced with compile-time pre-calculation. Although I can't say whether GCC can actually do this.

    In C++ (even though your question is tagged C) language a planned new feature is a constexpr declaration specifier that serves a similar purpose and supposed to have the effect you describe.

    0 讨论(0)
  • 2020-12-06 17:51

    It depends. If the compiler can do the math exactly as it would be done at runtime, and if link time optimizations are performed, and if the library is kept in some sort of intermediate form, then yes it could be done.

    Most compilers don't do all of that.

    0 讨论(0)
提交回复
热议问题