Sepideh Abadpour
Sepideh Abadpour

Reputation: 2598

Why do we use pre processor directives to define variables?

I have a piece of code like this:

/* T matrix */
#define T11     0
#define T12_re  1
#define T12_im  2

int main(int argc, char *argv[])
{
    return 1;
}

my question is why did it use preprocessor directives to define global variables and did not simply used a code like this:

/* T matrix */
double T11 = 0;
double T12_re = 1;
double T12_im = 2;

int main(int argc, char *argv[])
{
    return 1;
}

Upvotes: 5

Views: 1752

Answers (4)

Lorah Attkins
Lorah Attkins

Reputation: 5856

I'll try to enumerate pros, the other answers already cover the cons.

  1. This is a concise way to create a constant

     #define PI 3.14
    

    PI will be replaced by the preprocessor with 3.14 every time it is encountered, creating a named representation of your constant value

  2. The alternative

     double const pi = 3.14; 
    

    can be hacked like so

     const_cast<double>(pi) = 2.72; 
    

    and this causes undefined behaviour. The textual replacement offered by macros is immune to const_cast

  3. Since C++11 you can better embed type information in literals, aleviating (a bit) the typesafety considerations. See here more, but for a brief example consider eg you can always declare a ten seconds countdown constant with type safety

    #define CountDown 10s
    
  4. Last but not least ... reality is a beach (I hope this passes censorship). When dealing with legacy code you may face something like

    #define C1  112
    #define C2  113
    ....
    #define C332 443
    

    and this begs the question : Do you opt for consistency or programming style when ammending the above list?. Ofcourse the constants may be many more and scattered all around the place, and ofcourse there's always a choice to be made ...

Upvotes: 0

FelipeDurar
FelipeDurar

Reputation: 1179

Pre processor directives isn't used to define variables, the #define is just a way to facilitate the use of codes that you will use several times or that in the future you can modify without changing any line you put the code. The #define just replace one value to other, for example:

#define PI 3.14159265
....
    float diameter = (circ / PI);

The big difference between use #define and constant or variable, is that the use of #define don't allocates memory for this value, during the compilation the compilator just replace the PI to 3.14159265 in the code. define is used of this way because during the compilation is unchangeable (In the same manner as the constants) and doesn't allocate memory.

during the compilation the C++ compilator will generate a code with the defines replaced, so the above code during the compilation will be like this:

float diameter = (circ / 3.14159265);

if you want to allocate memory, just use constants:

const float PI = 3.14159265;

obs (#define is used too as macros)

Upvotes: 0

Wojtek Surowka
Wojtek Surowka

Reputation: 20993

The definitive answer to your question why is not possible - there is no reason to use obsolete constructs like those #defines. The main reason is that in the old times this was the only way to define constants (because we are talking about constants not variables. So the main reason is lack of knowledge.

Don't use such constructs - use proper C++ constants, like

const double T12_re = 0.1;

Upvotes: 1

Preprocessor symbols are not variables. In your first code, T13_im (etc...) is not a variable (but a preprocessed name, expanded to 4 at parsing time)

In your second code (it does not compile as you wrote it), you might have

const double  T12_re=  1.0;

Then you have declared a variable T12_re of const double type.

Read the wikipage on the C preprocessor, the documentation of GNU cpp and realize that the compiler sees only the preprocessed form; for your file yoursource.cc you could get the preprocessed form yoursource.ii using the command
g++ -Wall -C -E yoursource.cc > yoursource.ii then use a pager or editor to glance inside the generated yoursource.ii

Sometimes, the preprocessor permits cute tricks like this. And you cannot always use variables. For instance, the case expression should be a compile-time constant and cannot be in C a const int variable. (You could use some enum, and it is different in C and in C++).

Upvotes: 1

Related Questions