“static const” vs “#define” vs “enum”

后端 未结 17 1483
一生所求
一生所求 2020-11-21 05:45

Which one is better to use among the below statements in C?

static const int var = 5;

or

#define var 5

o

相关标签:
17条回答
  • 2020-11-21 06:06

    We looked at the produced assembler code on the MBF16X... Both variants result in the same code for arithmetic operations (ADD Immediate, for example).

    So const int is preferred for the type check while #define is old style. Maybe it is compiler-specific. So check your produced assembler code.

    0 讨论(0)
  • 2020-11-21 06:07

    Another drawback of const in C is that you can't use the value in initializing another const.

    static int const NUMBER_OF_FINGERS_PER_HAND = 5;
    static int const NUMBER_OF_HANDS = 2;
    
    // initializer element is not constant, this does not work.
    static int const NUMBER_OF_FINGERS = NUMBER_OF_FINGERS_PER_HAND 
                                         * NUMBER_OF_HANDS;
    

    Even this does not work with a const since the compiler does not see it as a constant:

    static uint8_t const ARRAY_SIZE = 16;
    static int8_t const lookup_table[ARRAY_SIZE] = {
        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; // ARRAY_SIZE not a constant!
    

    I'd be happy to use typed const in these cases, otherwise...

    0 讨论(0)
  • 2020-11-21 06:07

    If you can get away with it, static const has a lot of advantages. It obeys the normal scope principles, is visible in a debugger, and generally obeys the rules that variables obey.

    However, at least in the original C standard, it isn't actually a constant. If you use #define var 5, you can write int foo[var]; as a declaration, but you can't do that (except as a compiler extension" with static const int var = 5;. This is not the case in C++, where the static const version can be used anywhere the #define version can, and I believe this is also the case with C99.

    However, never name a #define constant with a lowercase name. It will override any possible use of that name until the end of the translation unit. Macro constants should be in what is effectively their own namespace, which is traditionally all capital letters, perhaps with a prefix.

    0 讨论(0)
  • 2020-11-21 06:07

    It is ALWAYS preferable to use const, instead of #define. That's because const is treated by the compiler and #define by the preprocessor. It is like #define itself is not part of the code (roughly speaking).

    Example:

    #define PI 3.1416
    

    The symbolic name PI may never be seen by compilers; it may be removed by the preprocessor before the source code even gets to a compiler. As a result, the name PI may not get entered into the symbol table. This can be confusing if you get an error during compilation involving the use of the constant, because the error message may refer to 3.1416, not PI. If PI were defined in a header file you didn’t write, you’d have no idea where that 3.1416 came from.

    This problem can also crop up in a symbolic debugger, because, again, the name you’re programming with may not be in the symbol table.

    Solution:

    const double PI = 3.1416; //or static const...
    
    0 讨论(0)
  • 2020-11-21 06:07

    Although the question was about integers, it's worth noting that #define and enums are useless if you need a constant structure or string. These are both usually passed to functions as pointers. (With strings it's required; with structures it's much more efficient.)

    As for integers, if you're in an embedded environment with very limited memory, you might need to worry about where the constant is stored and how accesses to it are compiled. The compiler might add two consts at run time, but add two #defines at compile time. A #define constant may be converted into one or more MOV [immediate] instructions, which means the constant is effectively stored in program memory. A const constant will be stored in the .const section in data memory. In systems with a Harvard architecture, there could be differences in performance and memory usage, although they'd likely be small. They might matter for hard-core optimization of inner loops.

    0 讨论(0)
  • 2020-11-21 06:08

    #define var 5 will cause you trouble if you have things like mystruct.var.

    For example,

    struct mystruct {
        int var;
    };
    
    #define var 5
    
    int main() {
        struct mystruct foo;
        foo.var = 1;
        return 0;
    }
    

    The preprocessor will replace it and the code won't compile. For this reason, traditional coding style suggest all constant #defines uses capital letters to avoid conflict.

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