Why use #define instead of a variable

C++C Preprocessor

C++ Problem Overview


What is the point of #define in C++? I've only seen examples where it's used in place of a "magic number" but I don't see the point in just giving that value to a variable instead.

C++ Solutions


Solution 1 - C++

The #define is part of the preprocessor language for C and C++. When they're used in code, the compiler just replaces the #define statement with what ever you want. For example, if you're sick of writing for (int i=0; i<=10; i++) all the time, you can do the following:

#define fori10 for (int i=0; i<=10; i++)

// some code...

fori10 {
    // do stuff to i
}

If you want something more generic, you can create preprocessor macros:

#define fori(x) for (int i=0; i<=x; i++)
// the x will be replaced by what ever is put into the parenthesis, such as
// 20 here
fori(20) {
    // do more stuff to i
}

It's also very useful for conditional compilation (the other major use for #define) if you only want certain code used in some particular build:

// compile the following if debugging is turned on and defined
#ifdef DEBUG
// some code
#endif

Most compilers will allow you to define a macro from the command line (e.g. g++ -DDEBUG something.cpp), but you can also just put a define in your code like so:

#define DEBUG

Some resources:

  1. Wikipedia article
  2. C++ specific site
  3. Documentation on GCC's preprocessor
  4. Microsoft reference
  5. C specific site (I don't think it's different from the C++ version though)

Solution 2 - C++

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.

Solution 3 - C++

I got in trouble at work one time. I was accused of using "magic numbers" in array declarations.

Like this:

int Marylyn[256], Ann[1024];

The company policy was to avoid these magic numbers because, it was explained to me, that these numbers were not portable; that they impeded easy maintenance. I argued that when I am reading the code, I want to know exactly how big the array is. I lost the argument and so, on a Friday afternoon I replaced the offending "magic numbers" with #defines, like this:

 #define TWO_FIFTY_SIX 256
 #define TEN_TWENTY_FOUR 1024

 int Marylyn[TWO_FIFTY_SIX], Ann[TEN_TWENTY_FOUR];

On the following Monday afternoon I was called in and accused of having passive defiant tendencies.

Solution 4 - C++

#define can accomplish some jobs that normal C++ cannot, like guarding headers and other tasks. However, it definitely should not be used as a magic number- a static const should be used instead.

Solution 5 - C++

C didn't use to have consts, so #defines were the only way of providing constant values. Both C and C++ do have them now, so there is no point in using them, except when they are going to be tested with #ifdef/ifndef.

Solution 6 - C++

Most common use (other than to declare constants) is an include guard.

Solution 7 - C++

Define is evaluated before compilation by the pre-processor, while variables are referenced at run-time. This means you control how your application is built (not how it runs)

Here are a couple examples that use define which cannot be replaced by a variable:

  1. #define min(i, j) (((i) < (j)) ? (i) : (j))
    note this is evaluated by the pre-processor, not during runtime

  2. http://msdn.microsoft.com/en-us/library/8fskxacy.aspx

Solution 8 - C++

The #define allows you to establish a value in a header that would otherwise compile to size-greater-than-zero. Your headers should not compile to size-greater-than-zero.

// File:  MyFile.h

// This header will compile to size-zero.
#define TAX_RATE 0.625

// NO:  static const double TAX_RATE = 0.625;
// NO:  extern const double TAX_RATE;  // WHAT IS THE VALUE?

EDIT: As Neil points out in the comment to this post, the explicit definition-with-value in the header would work for C++, but not C.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGreenerView Question on Stackoverflow
Solution 1 - C++supercheetahView Answer on Stackoverflow
Solution 2 - C++Paul TomblinView Answer on Stackoverflow
Solution 3 - C++HarpeeView Answer on Stackoverflow
Solution 4 - C++PuppyView Answer on Stackoverflow
Solution 5 - C++user2100815View Answer on Stackoverflow
Solution 6 - C++YXDView Answer on Stackoverflow
Solution 7 - C++DanJView Answer on Stackoverflow
Solution 8 - C++charleyView Answer on Stackoverflow