How could my code tell a compile-time constant versus a variable?

后端 未结 3 2046
情话喂你
情话喂你 2020-12-10 08:32

Here\'s my problem. I have a BINARY_FLAG macro:

#define BINARY_FLAG( n ) ( static_cast( 1 << ( n ) ) )

Whic

相关标签:
3条回答
  • 2020-12-10 08:37

    This is simpler than you think :)

    Let's have a look:

    #include <cassert>
    
    static inline int FLAG(int n) {
        assert(n>=0 && n<32);
        return 1<<n;
    }
    
    int test1(int n) {
        return FLAG(n);
    }
    int test2() {
        return FLAG(5);
    }
    

    I don't use MSVC, but I compiled with Mingw GCC 4.5:

    g++ -c -S -O3 08042.cpp

    The resulting code for first method looks like:

    __Z5test1i:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $24, %esp
        movl    8(%ebp), %ecx
        cmpl    $31, %ecx
        ja  L4
        movl    $1, %eax
        sall    %cl, %eax
        leave
        ret
    L4:
        movl    $4, 8(%esp)
        movl    $LC0, 4(%esp)
        movl    $LC1, (%esp)
        call    __assert
        .p2align 2,,3
    

    And the second:

    __Z5test2v:
        pushl   %ebp
        movl    %esp, %ebp
        movl    $32, %eax
        leave
        ret
    

    See? The compiler is smart enough to do it for you. No need for macros, no need for metaprogramming, no need for C++0x. As simple as that.

    Check if MSVC does the same... But look - it's really easy for the compiler to evaluate a constant expression and drop the unused conditional branch. Check it if you want to be sure... But generally - trust your tools.

    0 讨论(0)
  • 2020-12-10 08:40

    I suggest you use two macros. BINARY_FLAG CONST_BINARY_FLAG That will make your code easier to grasp for others. You do know, at the time of writing, if it is a const or not. And I would in no case worry about runtime overhead. Your optimizer, at least in VS, will sort that out for you.

    0 讨论(0)
  • 2020-12-10 08:50

    It's not possible to pass an argument to a macro or function and determine if it's compile time constant or a variable.

    The best way is that you #define BINARY_FLAG(n) with compile time code and place that macro everywhere and then compile it. You will receive compiler-errors at the places where n is going to be runtime. Now, you can replace those macros with your runtime macro BINARY_FLAG_RUNTIME(n). This is the only feasible way.

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