The authors support the use of symbolic constants with #define and a name in capitals. What's the point since we can do the say with assigning a variable with a constant value, i.e. int step = 20
I'm a begginer in C...
On
The authors support the use of symbolic constants with #define and a name in capitals. What's the point since we can do the say with assigning a variable with a constant value, i.e. int step = 20
Variables, even if declared with the const qualifier, are not on the language spec's list of expressions that are or can appear in "constant expressions". Constant expressions are required for the dimensions of (ordinary) arrays and in initializers of variables with static storage duration, among other places. Macros that expand to constants or constant expressions can be used in these places.
Variables occupy storage, whereas macro-defined constants effectively do not. That is, variables impose a memory usage cost.
Variables' values need to be read from storage to be used (to a first approximation), whereas macro constants generally do not. That is, variables impose a performance cost.
Variables declared in header files either are static, or are subject to the one-definition rule. The former tends to increase the required storage and sometimes draws useless compiler diagnostics. The latter makes code more complicated and makes the value of the variable more difficult to discover at development time. None of that applies to macros.
At the time C was developed, compilers had little or no ability to remember the values of variables, and it was early in the development of the semantics of programs. The major purpose of a declaration
int step = 20;was to cause memory to be reserved forstep, to remember its type wasint, and to generate instructions or other object-module code that initialized the memory to 20.Remembering “values” of macro names was managed in a separate part of the compilation process, called a preprocessor, whose job was to process the directives beginning with
#.The original idea was that
int step = 20;would causestepto be set to 20 when the program started running. Knowing it was 20 when the program was being compiled was not part of the initial plan.There are places in C where the compiler needs to know a value at the time it is compiling. For example, when an array is defined outside a function, as with
int x[328];, the compiler needs to know how much space to reserve for the array. It must have a “constant” value for that, not a “variable” likestep. The compiler would not know what to do withint x[step];. The preprocessor took care of this; it processed the#definedirectives and replaced occurrences of the macrostepwith the replacement token20. Then the compiler would seeint x[20];, notint x[step];, and that would work.Compilers have developed a great deal over the years, and today a preprocessor may be integrated into the compiler. Additionally, code has been written for some compilers that will remember the values of variables that are defined as constant (with
const) and allow their use in some places where constants are needed. However, this has not yet been made a part of the C standard, and not all compilers support it. (C++ is further along in this.)Also consider this:
At
int x[step];, we can figurestephas the value 20, taking the initialization to occur as soon as we compileint step = 20;instead of when the program starts running. But what is the value ofstepatint y[step];? The value could have changed in the call tofoo, since the code infoomight assign a new value tostep. (Modern C allows defining arrays with values computed at run-time but does not currently require compilers to support that.) So there are various problems attempting to use variables for values the compiler needs to know when it is compiling.