Preprocessor directive & const types – differences?

Share the Article

Preprocessor directive or #define is the traditional C-style way of specifying constant items. This is also known as macros, because the pre-processor just does substitution of values across the body of code, before formal compiler runs.

#define MAXSIZE 1024

The C++ way to specify constant is to use const keyword:

const int MAXSIZE=1024

Space: The preprocessor blind substitution of MAXSIZE may result in multiple copies in the code. The preprocessor phase runs before the compiler, hence the compiler may never see the name MAXSIZE.

Whereas, in case of const inst MAXSIZE, the compiler will store the variable in symbol table and there will be only one copy.

Example, Smaller code with floating-type constants

When const is float or double value then use of const may save space because, there will be only one copy of floating-point value

const double PIVAL = 3.142

In case of #define, multiple copies of the floating value will exist in the code.

Debugging: The use of preprocessor directive, #define may also cause problem with debuggers, the debuggers will not understand the name but will only see a value.


Using the const int, it is possible to control the scope and accessibility, whereas, it is difficult to control the scope for #define.

class MainFunda { private: const int MAXSIZE = 1024; };

Here, the MAXSIZE will live in scope of class.

Also, it is encapsulated within class as private variable.

No such things are possible with #define.

Class specific constants

To limit the scope of constant to a class, the constant has to be made member of class and of type static.

class MainFunda { private: static const int MAXSIZE = 1024; };

Static means that there will be only one copy of the variable for all the objects.

Special Exception for in-class definition : Above is a declaration for MAXSIZE, this is not a definition. C++ mandates that program provide a definition for any declaration that is used, but class-specific constants which are of type static and of integer (e.g., int, char, bool) are an exception.

Program can declare them and use them without providing a definition, if no address of these variables is taken. If program takes the address of a class member constant, then a separate definition must be provided as shown below:

const int MainFunda::MAXSIZE;

In-class initialization like above is possible only for integer type variables and not for types like, floating-type or complex objects.

class MainFunda { private: static const double PIVAL; //declaration }; const double MainFunda::PIVAL = 3.142; //definition

Also, legacy compilers sometimes may not accept the in-class initialization above, because earlier it used to be illegal to provide an initial value at its point of declaration for class member variables.

The initial value can be provided in definition in implementation file and not in header.

Therefore, it was not possible to get the value of const variable during compilation of class. One scenario was to use the constant for declaring an array variable. For such scenarios, a hack using enum is available.

Enum Hack

The enum hack takes advantage of the property that enums leak the enumerated names in the scope where they are declared. Also, the values of an enumerated type can be used just like int.

class MainFunda { private: enum{MAXSIZE=5}; int arrary[MAXSIZE]; };

This is a hack because, it is not possible to take address or reference of the enumerated name.

Main Funda: const types are better way to work with constant items than preprocessor directive or macros

Related Topics:

What are differences : #define & const built-in types?
Understanding Constant Variables
Why variable declaration should not be done at the start? 
Concept of Inline Functions
Understanding array version of new[] & delete[]
How to overload global version of new & delete ?
How to overload new & delete for a class?
How to overload placement new operator?
Benefit of using “override” keyword?
What are Lambda?
Explaining C++ casts
How to stop compiler from generating special member functions?
 What are the drawbacks of using enum ?
Parametrized constructor
What is an explicit constructor ?
Basics of throwing and catching exception

Share the Article

Leave a Reply

Your email address will not be published. Required fields are marked *