Why Would Someone Use #Define to Define Constants

Why would someone use #define to define constants?

#define has many different applications, but your question seems to be about one specific application: defining named constants.

In C++ there's rarely a reason to use #define to define named constants.

#define is normally widely used in C code, since C language is significantly different from C++ when it comes to defining constants. In short, const int objects are not constants in C, which means that in C the primary way to define a true constant is to use #define. (Also, for int constants one can use enums).

What is the benefit of using #define to declare a constant?

(This is a C++ answer. In C, there is a major advantage to using macros, which is that they are pretty much the only way you can get a true constant-expression.)


What is the benefit of using #define to declare a constant?

There isn't one.

I have seen a lot of programs using #define at the beginning.

Yes, there is a lot of bad code out there. Some of it is legacy, and some of it is due to incompetence.

Why shouldn't I declare a constant global variable instead ?

You should.

A const object is not only immutable, but has a type and is far easier to debug, track and diagnose, since it actually exists at compilation time (and, crucially, has a name in a debug build).

Furthermore, if you abide by the one-definition rule, you don't have to worry about causing an almighty palaver when you change the definition of a macro and forget to re-compile literally your entire project, and any code that is a dependent of that project.

And, yes, it's ironic that const objects are still called "variables"; of course, in practice, they are not variable in the slightest.

Why do most C developers use define instead of const?

There is a very solid reason for this: const in C does not mean something is constant. It just means a variable is read-only.

In places where the compiler requires a true constant (such as for array sizes for non-VLA arrays), using a const variable, such as fieldWidth is just not possible.

Why use #define instead of a variable

Mostly stylistic these days. When C was young, there was no such thing as a const variable. So if you used a variable instead of a #define, you had no guarantee that somebody somewhere wouldn't change the value of it, causing havoc throughout your program.

In the old days, FORTRAN passed even constants to subroutines by reference, and it was possible (and headache inducing) to change the value of a constant like '2' to be something different. One time, this happened in a program I was working on, and the only hint we had that something was wrong was we'd get an ABEND (abnormal end) when the program hit the STOP 999 that was supposed to end it normally.

Shall I prefer constants over defines?

No, in general you should not use const-qualified objects in C to create names constants. In order to create a named constant in C you should use either macros (#define) or enums. In fact, C language has no constants, in the sense that you seem to imply. (C is significantly different from C++ in this regard)

In C language the notions of constant and constant expression are defined very differently from C++. In C constant means a literal value, like 123. Here are some examples of constants in C

123
34.58
'x'

Constants in C can be used to build constant expressions. However, since const-qualified objects of any type are not a constants in C, they cannot be used in constant expressions, and, consequently, you cannot use const-qualified objects where constant expressions are required.

For example, the following is not a constant

const int C = 123; /* C is not a constant!!! */

and since the above C is not a constant, it cannot be used to declare an array type in file scope

typedef int TArray[C]; /* ERROR: constant expression required */

It cannot be used as a case label

switch (i) {
case C: ; /* ERROR: constant expression required */
}

It cannot be used as bit-field width

struct S {
int f : C; /* ERROR: constant expression required */
};

It cannot be used as an initializer for an object with static storage duration

static int i = C; /* ERROR: constant expression required */

It cannot be used as a enum initializer

enum {
E = C /* ERROR: constant expression required */
};

i.e it cannot be used anywhere where a constant is required.

This might seem counter-intuitive, but this is how C the language is defined.

This is why you see these numerous #define-s in the code you are working with. Again, in C language const-qualified object have very limited use. They are basically completely useless as "constants", which is why in C language you are basically forced to use #define or enums to declare true constants.

Of course, in situations when a const-qualified object works for you, i.e. it does what you want it to do, it is indeed superior to macros in many ways, since it is scoped and typed. You should probably prefer such objects where applicable, however in general case you'll have to take into account the above limitations.

Definition of constant variable vs. #define

In C, const int c; means that c can't be modified during the run of program. However, c is not a constant during compile time and can not be used in constant expressions. So for example the program:

const int MAX = 10;
int a[MAX];

does not compile, while:

#define MAX 10
int a[MAX];

does.

In C++, const variables are true compile-time constants, so there may be less reasons to use #define for it. An example where #define is necessary is when you need to use the constant in an #if directive.

In C++, is it better to use #define or const to avoid magic numbers?

Don't worry about efficiency in this case since all of them will be computed in compile-time.

You should stop using Macros (at least to define constants) whenever you can. Macros are wild things against namespaces and scopes. On the other hand const objects have type and this can reduce unintended mistakes.

It's always useful to read Stroustrup's piece of advises: "So, what's wrong with using macros?"

What is the difference between #define and const?

The #define directive is a preprocessor directive; the preprocessor replaces those macros by their body before the compiler even sees it. Think of it as an automatic search and replace of your source code.

A const variable declaration declares an actual variable in the language, which you can use... well, like a real variable: take its address, pass it around, use it, cast/convert it, etc.

Oh, performance: Perhaps you're thinking that avoiding the declaration of a variable saves time and space, but with any sensible compiler optimisation levels there will be no difference, as constant values are already substituted and folded at compile time. But you gain the huge advantage of type checking and making your code known to the debugger, so there's really no reason not to use const variables.

Advantage and disadvantages of #define vs. constants?

Constants allow you to specify a datatype, which is (usually) an advantage. Macros are much more flexible, and therefore can get you into much more trouble if you're not careful.

Best practice is to use constants as much as possible, and use #define only when you really need a macro, not just a named literal value.

#defining constants in C++

Is it considered bad programming practice to #define constants in C++?

Yes, because all macros (which are what #defines define) are in a single namespace and they take effect everywhere. Variables, including const-qualified variables, can be encapsulated in classes and namespaces.

Macros are used in C because in C, a const-qualified variable is not actually a constant, it is just a variable that cannot be modified. A const-qualified variable cannot appear in a constant expression, so it can't be used as an array size, for example.

In C++, a const-qualified object that is initialized with a constant expression (like const int x = 5 * 2;) is a constant and can be used in a constant expression, so you can and should use them.



Related Topics



Leave a reply



Submit