tags:

views:

1949

answers:

7

Which one is better to use among the below statements in c:

static const int var=5;

or

#define var 5
+19  A: 

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 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 :)

Matthieu M.
Agreed - also with #define there's a general danger of mangling code as the preprocessor is not aware of syntax.
NeilDurant
Its better to use #if than #ifdef , but otherwise I agree. +1.
Tim Post
See this : http://stackoverflow.com/questions/135069/ifdef-vs-if-which-is-better-safer regarding the difference. Actually, CCAN has implemented that as part of their style guidelines (one of Rusty's pet peeves).
Tim Post
A: 

Don't think there's an answer for "which is always best" but, as Matthieu said

static const

is type safe. My biggest pet peeve with #define, though is when debugging in MSVS you cannot watch the variable, it gives an error that the symbol cannot be found.

Afcrowe
+1  A: 

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.

sellibitze
+13  A: 

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). 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).

AndreyT
+6  A: 

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.

David Thornley
Unfortunately, this is not the case with C99. `const` in C99 is still not a real constant. You can declare array size with a `const` in C99, but only because C99 supports Variable Length Arrays. For this reason, it will only work where VLAs are allowed. For example, even in C99, you still can't use a `const` to declare size of a member array in a `struct`.
AndreyT
+18  A: 

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.
  • (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.

Jonathan Leffler
A: 

The difference b/w static const and #define is that the former uses the memory and the later doesnot use the memory for storage. Secondly, you cannot pass the address of an #define whereas you can pass the address of a static const. Actually it is depending on what circumstance we are under, we need to select one amoung these two. Both are at their best under different circumstances. Please dont assume that one is better that other... :-)

If that would have been the case, Dennis ritchie (sorry, if I have spelt the great man's name incorrectly) would have kept the best one alone... hahaha... :-)

wrapperm