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

后端 未结 17 1486
一生所求
一生所求 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:09

    Incidentally, an alternative to #define, which provides proper scoping but behaves like a "real" constant, is "enum". For example:

    enum {number_ten = 10;}
    

    In many cases, it's useful to define enumerated types and create variables of those types; if that is done, debuggers may be able to display variables according to their enumeration name.

    One important caveat with doing that, however: in C++, enumerated types have limited compatibility with integers. For example, by default, one cannot perform arithmetic upon them. I find that to be a curious default behavior for enums; while it would have been nice to have a "strict enum" type, given the desire to have C++ generally compatible with C, I would think the default behavior of an "enum" type should be interchangeable with integers.

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

    Generally speaking:

    static const
    

    Because it respects scope and is type-safe.

    The only caveat I could see: if you want the variable to be possibly defined on the command line. There is still an alternative:

    #ifdef VAR // Very bad name, not long enough, too general, etc..
      static int const var = VAR;
    #else
      static int const var = 5; // default value
    #endif
    

    Whenever possible, instead of macros / ellipsis, use a type-safe alternative.

    If you really NEED to go with a macro (for example, you want __FILE__ or __LINE__), then you'd better name your macro VERY carefully: in its naming convention Boost recommends all upper-case, beginning by the name of the project (here BOOST_), while perusing the library you will notice this is (generally) followed by the name of the particular area (library) then with a meaningful name.

    It generally makes for lengthy names :)

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

    In C, specifically? In C the correct answer is: use #define (or, if appropriate, enum)

    While it is beneficial to have the scoping and typing properties of a const object, in reality const objects in C (as opposed to C++) are not true constants and therefore are usually useless in most practical cases.

    So, in C the choice should be determined by how you plan to use your constant. For example, you can't use a const int object as a case label (while a macro will work). You can't use a const int object as a bit-field width (while a macro will work). In C89/90 you can't use a const object to specify an array size (while a macro will work). Even in C99 you can't use a const object to specify an array size when you need a non-VLA array.

    If this is important for you then it will determine your choice. Most of the time, you'll have no choice but to use #define in C. And don't forget another alternative, that produces true constants in C - enum.

    In C++ const objects are true constants, so in C++ it is almost always better to prefer the const variant (no need for explicit static in C++ though).

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

    In C #define is much more popular. You can use those values for declaring array sizes for example:

    #define MAXLEN 5
    
    void foo(void) {
       int bar[MAXLEN];
    }
    

    ANSI C doesn't allow you to use static consts in this context as far as I know. In C++ you should avoid macros in these cases. You can write

    const int maxlen = 5;
    
    void foo() {
       int bar[maxlen];
    }
    

    and even leave out static because internal linkage is implied by const already [in C++ only].

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

    It depends on what you need the value for. You (and everyone else so far) omitted the third alternative:

    1. static const int var = 5;
    2. #define var 5
    3. enum { var = 5 };

    Ignoring issues about the choice of name, then:

    • If you need to pass a pointer around, you must use (1).
    • Since (2) is apparently an option, you don't need to pass pointers around.
    • Both (1) and (3) have a symbol in the debugger's symbol table - that makes debugging easier. It is more likely that (2) will not have a symbol, leaving you wondering what it is.
    • (1) cannot be used as a dimension for arrays at global scope; both (2) and (3) can.
    • (1) cannot be used as a dimension for static arrays at function scope; both (2) and (3) can.
    • Under C99, all of these can be used for local arrays. Technically, using (1) would imply the use of a VLA (variable-length array), though the dimension referenced by 'var' would of course be fixed at size 5.
    • (1) cannot be used in places like switch statements; both (2) and (3) can.
    • (1) cannot be used to initialize static variables; both (2) and (3) can.
    • (2) can change code that you didn't want changed because it is used by the preprocessor; both (1) and (3) will not have unexpected side-effects like that.
    • You can detect whether (2) has been set in the preprocessor; neither (1) nor (3) allows that.

    So, in most contexts, prefer the 'enum' over the alternatives. Otherwise, the first and last bullet points are likely to be the controlling factors — and you have to think harder if you need to satisfy both at once.

    If you were asking about C++, then you'd use option (1) — the static const — every time.

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

    A simple difference:

    At pre-processing time, the constant is replaced with its value. So you could not apply the dereference operator to a define, but you can apply the dereference operator to a variable.

    As you would suppose, define is faster that static const.

    For example, having:

    #define mymax 100
    

    you can not do printf("address of constant is %p",&mymax);.

    But having

    const int mymax_var=100
    

    you can do printf("address of constant is %p",&mymax_var);.

    To be more clear, the define is replaced by its value at the pre-processing stage, so we do not have any variable stored in the program. We have just the code from the text segment of the program where the define was used.

    However, for static const we have a variable that is allocated somewhere. For gcc, static const are allocated in the text segment of the program.

    Above, I wanted to tell about the reference operator so replace dereference with reference.

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