When to use const and when to use #define

Asked

Viewed 11,758 times

9

Since the two do the same function there is some 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 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 code is compiled and executed it reproduces the following result:

value of area : 50

3 answers

12


They don’t do the same thing. They’re semantically different. Even if they often produce the same result, it’s an eventuality.

#define

The first is a preprocessor directive code. It is 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 the compilation that does not always bring the results expected by a more naive or careless 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 get creative with this and everything can explode in your face ;) You can control the flow of compilation based on these "constants". You can change any part of the code, not just values.

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

const

This is a identifier statement present in the code with scope and lifespan in the code. It’s verified 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.

You’ll notice a difference when you’re thrashing the code.

enum

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

  • 1

    vlw @bigown now I’ll stay tuned when I have to use const and #defines +1

3

There are some situations where you cannot 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 no

int *p = &xpto; // ok
int *p = &XPTO; // erro

1

Scott Meyers, in his book:

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

#define can be treated as if it were not part of the language itself. That’s 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 the 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 the 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 hair-file which you didn’t write, you would have no idea where this 2.33 came from, and I’d waste my time trying to find you.

The solution is to replace the macro with a constant:

const double Valor_X= 2.33

As a constant of language, Valor_x is definitely seen by the compilers and certainly is inserted into their symbol tables. In addition, 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 one #define. This is because the blind replacement of the pre-processor of the macro name VALORX by 2.33 may result in multiple copies of 2.33 in its object code, while the use of the constant Valor_x should never result in more than one copy.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.