When to use const and when to use # define

Since the two do the same function is there any difference between one and the other?

I will take the code from this site as an example C-Constants & Literals

The # define Preprocessor

#include <stdio.h>

#define LENGTH 10   
#define WIDTH  5
#define NEWLINE '\n'

int main() {

   int area;  
  
   area = LENGTH * WIDTH;
   printf("value of area : %d", area);
   printf("%c", NEWLINE);

   return 0;
}

When the code is compiled and executed it reproduces the following result:

Value of area: 50

The const Keyword

#include <stdio.h>

int main() {

   const int  LENGTH = 10;
   const int  WIDTH = 5;
   const char NEWLINE = '\n';
   int area;  
   
   area = LENGTH * WIDTH;
   printf("value of area : %d", area);
   printf("%c", NEWLINE);

   return 0;
}

When the code is compiled and executed it reproduces the following result:

Value of area: 50

Author: Comunidade, 2016-06-22

3 answers

They don't do the same thing. They are semantically different. Even if it is frequent to produce the same result, it is an eventuality.

#define

The first is a code preprocessor directive. It's just one text being replaced by another without any kind of verification. It can give all kinds of nonsense. It is a trick performed before compilation that does not always bring the results expected by a more naive or careless programmer. She lives since her include until the end of the file being compiled.

In general should be avoided whenever possible. But there are useful cases.

You can be creative with this and everything can explode in your face ;) you can control the flow of the build based on these "constants". You can change any part of the code, not just values.

See " # define " defines a global variable? and Why do you have so many parentheses in macro? (used in another context, but shows how complicated it is to do it right).

const

This is a identifier statement present in the code with scope and lifetime in the code. is checked by the compiler and has a type. It can be used in all circumstances where a variable would be used (in fact it is not entirely a constant). Compiler optimizations can directly access the value and avoid time and space consumption. Obviously this only occurs when it is viable.

Will notice a difference when is debugging the code.

enum

Also know the enum, it is even closer to #define, although they also have different semantics. It has almost all the advantages of the two without the main disadvantages. Contrary to what many believe, there may be a single constant value in an enumeration that will always be used during compilation and never stored, equal to #define, but it has context and compiler check.

 11
Author: Maniero, 2020-08-20 20:44:55

There are some situations where you can't use objects (variables with const)

#define XPTO 42
const int xpto = 42;

switch (valor) {
    case XPTO: // OK
    case xpto: // erro
}

int arraynormal[XPTO]; // OK
int arraynormal[xpto]; // erro (excepto VLA)

More generally: objects take up memory space; # defines do not

int *p = &xpto; // ok
int *p = &XPTO; // erro
 3
Author: pmg, 2016-06-22 14:18:01

Scott Meyers, in his book:

Effective C++ -55 ways to enhance your programs and projects says: "prefer compiler to preprocessor"

#define it can be treated as if it were not part of the language proper fingers. This is one of your problems.

When you do something like:

#define VALORX 2.33

It may be that the symbolic name VALORX is never seen by compilers; it can be removed by preprocessor before the source code reaches a compiler.

As a result, the name VALORX may not enter the symbol table, which can be confusing if you receive an error during compilation involving the use of the constant, as the error message may refer to 2.33, but not to VALORX.

If VALORX was defined in a cabe file- that you did not write, you would have no idea where this 2.33 came from, and it would waste time trying to find him.

The solution is to replace the macro with a constant:

const double Valor_X= 2.33

As a language constant, Value_x is definitely seen by compilers and certainly is inserted into their symbol tables. Also, in the case of a floating point constant (as in this example), the use of the constant can lead to a smaller code than with um #define. This is because the blind replacement of the preprocessor from the macro name VALORX by 2.33 can result in multiple copies of 2.33 in its object code, while the use of the constant x value should never result in more than one copy.

 1
Author: borgomeister, 2017-01-13 18:11:11