When to use const and when to use #define

6

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

I'll 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

    
asked by anonymous 22.06.2016 / 15:51

3 answers

9

They do not 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 is just a text being replaced by another text without any type of verification. Can give all kinds of nonsense. It's a pre-compilation trick that does not always bring the results expected by a more naive or sloppy programmer. It lives from its inclusion to the end of the file being compiled.

In general it 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 build flow based on these "constants". You can change any part of the code, not just values.

const

The second is a handle declaration in the code with Scope and lifetime in code. It 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 totally a constant). Compiler optimizations can directly access value and avoid consumption of time and space. Obviously this only occurs when it is feasible.

You'll notice a difference when debugging the code.

enum

Also know the enum , it is even closer to #define , even though also have different semantics. It possesses almost all the advantages of the two without the major 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 checking.

    
22.06.2016 / 16:19
1

There are some situations where you can not 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 not

int *p = &xpto; // ok
int *p = &XPTO; // erro
    
22.06.2016 / 16:18
1

Scott Meyers, in his book:

  

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

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

When you do something like:

% of% VALORX 2.33

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

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

If VALORX is defined in a header file, you did not write, you would have no idea where this 2.33 came from, and I would spend time trying to find you.

The solution is to replace the macro with a constant:

#define

As a language constant, Value_X is definitely seen by compilers and certainly is inserted into their tables of symbols. In addition, in the case of a floating-point constant (as in example), the use of the constant can lead to a smaller code than with a const double Valor_X= 2.33 . This is because blind replacement of the preprocessor of the VALORX macro name by 2.33 may 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.

    
13.01.2017 / 19:11