2

Possible Duplicate:
“static const” vs “#define” in c

I am going through the K&R book and this question came up. How to best decide whether something should be its own variable or be defined as a symbolic constant?

Suppose we're dealing with const int myNumber = 12; , which also can be #define MY_NUMBER 12 is there a rule of thumb one should follow when deciding which whether a variable needs to be created or symbolic constant used?

Community
  • 1
  • 1
James Raitsev
  • 92,517
  • 154
  • 335
  • 470
  • See [static const vs #define](http://stackoverflow.com/questions/1674032/static-const-vs-define-in-c/), which also discusses `enum` as a frequently useful alternative. – Jonathan Leffler Dec 25 '11 at 02:40

2 Answers2

7

The real question is whether n should be a declared const object or a macro. (The question's title currently refers to "a variable or a symbolic constant".)

This:

const int myNumber = 12;

makes myNumber const but not constant. The const keyword means that you're not allowed to modify the object it applies to, but it doesn't make it constant. Switch labels, for example, must be constant; you can't write:

switch (n) {
    case myNumber:
    ...
}

So if you need to use myNumber in a context that requires a constant expression, the above isn't going to work.

On the other hand, a macro:

#define MY_NUMBER 12

means that any use of MY_NUMBER is replaced by a literal 12, which is constant. A drawback of macros is that they're not scoped the way declared objects are; the name MY_NUMBER is visible from the definition to the end of the source file, which can cause conflicts. (Note that macro names are conventionally written in all-caps, specifically to draw attention to them.) In effect, the preprocessor, which is where macros are handled is another language tacked onto C.

For constants of type int, there's another trick you can use (I don't think K&R mention this):

enum { myNumber = 12 };

This creates an anonymous enumeration type, which you aren't actually going to use. myNumber is actually of type int, not of the enumeration type, and you can use it the same way you'd use the literal 12. You can even use an expression to define its value, as long as the expression is constant:

enum { myNumber = 3 * 4 };

(C++ has different rules. In C++, const int myNumber = 12; does make myNumber a constant expression -- and enumeration constants are of the enumerated type, not of type int.)

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
1

If you're hard-coding a constant like "2" ... then it's a candidate for symbolic parameter.

ADDENDUM:

You changed the question :)

Q: I am going through the K&R book and this question came up. How to best decide whether something should be its own variable or be defined as a symbolic parameter?

A: "Magic numbers" are bad. Use "#define SOME_MEANINGFUL_NAME 2" in preference to "2".

Q: Suppose were dealing with const int myNumber = 12; , which also can be #define MY_NUMBER 12 is there a rule of thumb one should follow when deciding which approach to take here?

A: If you're using C++ or C#, then you should probably use "const" in favor of "#define".

paulsm4
  • 114,292
  • 17
  • 138
  • 190