Reputation: 2598
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
Reputation: 5856
I'll try to enumerate pros, the other answers already cover the cons.
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
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
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
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
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
Reputation: 20993
The definitive answer to your question why is not possible - there is no reason to use obsolete constructs like those #define
s. 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
Reputation: 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