What is the difference in these two lines?

#define X 100
const int Y 100;

Apart from the fact that one is for X and the other is for Y (har har, very funny) effectively don't they do the same thing? Why would one be preferable over the other?

>effectively don't they do the same thing?
Somewhat. The define is a textual replacement. Anywhere you say X, it's turned into 100 before the code is compiled. Y, on the other hand, is an actual object that the compiler will recognize. You should choose the latter simply because there's fewer surprises with typing and the debugger can be more informative with an object than a literal value.

Anothere difference: defines can be changed but const can not. Anywhere in your program you can redefine X to be anything you want, including a string. You can not do that with a const int.

>You can not do that with a const int.
That's kind of a good thing...

Another difference is #define doesn't translate any memory allocation, whereas a const variable will cost some memory.

There is a third way for constants, use enums.

enum { X = 100 } ;

It's comparatively typesafe and doesn't use any memory. Restriction is of course that you can use it only for integer consts.

Anywhere in your program you can redefine X to be anything you want, including a string. You can not do that with a const int.

If one can do #undef followed by #define, then you can also, with some effort, modify a const by casting (of course not int to a string). :)

...modify a const by casting

really you should not.
a constant whose value is known at compile time
a. may (would) be placed into memory with read-only access by the compiler if it has a static storage class.
b. the compiler can (should) treat such a contant as if it is a literal constant. eg.

const size_t N = 78 ;
const_cast<size_t&>(N) = 100 ; // will compile because of the cast
int array[N] ; // will also compile, but the array size is 78, not 100
if( N > 80 ) { /* whatever */ } // dead code!
const int* ptr = &N ;
cout << N << '\t' << *ptr << '\n' ; // N, *ptr have different values

as narue said, that you cannot (should not) modify a const is a good thing.

however, const is handled by the compiler, not the preprocessor; therefore (unlike a #define) it is subject to scoping rules.

const int N = 78 ;
void foo()
{
  cout << N << '\n' ; // 78
  const int N = 100 ;
  cout << N << '\n' ; // 100
  {
     const string N = "N is a string!" ;
     cout << N << '\n' ; // N is a string!
   }
  cout << N << '\n' ; // 100
}
const void* init = cout << N << '\n' ; // 78
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.