[Home]
[Edit this page]
[Recent Changes]
[Special Pages]
[Help]
CppDefine
The preprocessor directive #define is used to define macros. Prefer consts, enums and inlines to #defines[1,7].
A macro, in programming, is a identifier that gets replaced by the compiler or preprocessor to its value throughout the source code (this is a replace only for compiling purposes, and only used during compilation, so the source file is not changed in any way).
Example:
This will print five times "Hello World!" followed by a newline. If you change the #define line to read
That's because the preprocessor, when see the COUNT in the "for" line, replaces it by its value (which is defined in the "#define" line). It is common practice to write macro's like COUNT in capitals: 'If you must use macro's, use ugly names with lots of capital letters' [6].
The preprocessor considers that the value of the macro is any character after the space following its name, up to the next newline, so it is not recommended that you use a semicolon (";") to end a macro definition, else it will be considered part of the macro and will, possibly, generate a syntax error somewhere in your code where you use the macro.
Prefer consts over this type of #define[1,7,8].
Example:
The above code would print "Increased: 1", since the initial value of the variable "i" is zero. The code the compiler will see, after preprocesing, is something like:
Since the macro value is "x+1" and "x", in the example, is the variable "i".
Prefer inlines over this type of #define[1,7,9].
[Edit this page] [Page history] [What links here] [Discuss this topic] [Printer Friendly]
CppDefine
(C++) #define
The preprocessor directive #define can be used for- Macros
- #include guards
- The assert statement
Macros
Avoid macros's [1,2,7] when using C++ as there are better, type-safe alternatives.The preprocessor directive #define is used to define macros. Prefer consts, enums and inlines to #defines[1,7].
A macro, in programming, is a identifier that gets replaced by the compiler or preprocessor to its value throughout the source code (this is a replace only for compiling purposes, and only used during compilation, so the source file is not changed in any way).
Example:
#define COUNT 5 int main() { for (int i = 0; i != COUNT; i++) { printf("Hello World!\n"); } }
- include <stdio.h>
This will print five times "Hello World!" followed by a newline. If you change the #define line to read
then the "Hello World!" will be printed ten times.
- define COUNT 10
That's because the preprocessor, when see the COUNT in the "for" line, replaces it by its value (which is defined in the "#define" line). It is common practice to write macro's like COUNT in capitals: 'If you must use macro's, use ugly names with lots of capital letters' [6].
The preprocessor considers that the value of the macro is any character after the space following its name, up to the next newline, so it is not recommended that you use a semicolon (";") to end a macro definition, else it will be considered part of the macro and will, possibly, generate a syntax error somewhere in your code where you use the macro.
Prefer consts over this type of #define[1,7,8].
Macro Functions
These are macros which can receive parameters.Example:
#define INCREASE(x) x+1 int main() { int i = 0; printf("Increased: %i\n", INCREASE(i)); }
- include <stdio.h>
The above code would print "Increased: 1", since the initial value of the variable "i" is zero. The code the compiler will see, after preprocesing, is something like:
int main()
{
int i = 0;
printf("Increased: %i\n", i+1);
}
Since the macro value is "x+1" and "x", in the example, is the variable "i".
Prefer inlines over this type of #define[1,7,9].
#include guards
The preprocessor statements #ifndef ,#define and #endif can be used for #include guards. These prevent a header file to be #included multiple times, causing a redeclaration error. Always write (internal) #include guards [3,10].Example
//Your header file
- ifndef __MYHEADERFILE_H
- define __MYHEADERFILE_H
- endif
The assert statement
Also #define is used for the debugging #define NDEBUG (e.g. used by assert). Assert liberally to document internal assumptions and invariants [4,5,11]double inverse(const double& value) { assert(value!=0.0); //Divisions by zero are illegal return 1.0/value; }
- include <iostream>
- include <cassert>
References
- 1) Scott Meyers. Effective C++ (3rd edition).ISBN: 0-321-33487-6. Item 2: Prefer consts, enums and inlines to #defines
- 2) Bjarne Stroustrup. The C++ Programming Language (3rd edition).ISBN: 0-201-88954-4. Chapter 7.9.4: 'Avoid macro's'
- 3) Herb Sutter,Andrei Alexandrescu. C++ coding standards: 101 rules, guidelines, and best practices. ISBN: 0-32-111358-6. Chapter 24: 'Always write internal #include guards. Never write external #include guards'.
- 4) Herb Sutter,Andrei Alexandrescu. C++ coding standards: 101 rules, guidelines, and best practices. ISBN: 0-32-111358-6. Chapter 68: 'Assert liberally to document internal assumptions and invariants'.
- 5) Bjarne Stroustrup. The C++ Programming Language (3rd edition).ISBN: 0-201-88954-4. Advice 24.5.18: 'Explicitly express preconditions, postconditions, and other assertions as assertions'.
- 6) Bjarne Stroustrup. The C++ Programming Language (3rd edition).ISBN: 0-201-88954-4. Chapter 7.9.10: 'If you must use macro's, use ugly names with lots of capital letters'.
- 7) Jarrod Hollingworth, Bob Swart, Mark Cashman, Paul Gustavson. Sams C++ Builder 6 Developer's Guide. ISBN: 0-672-32480-6. Chapter 3, paragraph 'Know when to use the preprocessor', lines 1-2: 'It is not appropriate to use the preprocessor for defining constants or for creating function macro's. Instead, you should use const variables or enum types for constants and use inline function (or inline template function) to replace a function macro.
- 8) Jesse Liberty. Sams teach yourself C++ in 24 hours. ISBN: 0-672-32224-2. Hour 21, chapter 'Using #define for constants': 'This is almost never a good idea, however, because #define merely makes a string substitution and does no type checking.'
- 9) Jesse Liberty. Sams teach yourself C++ in 24 hours. ISBN: 0-672-32224-2. Hour 21, chapter 'Macros versus functions and templates': 'Macros suffer from four problems in C++. [...] The final problem, however is the biggest: macros are not type safe. [...] Templates overcome this problem.'
- 10) Jesse Liberty. Sams teach yourself C++ in 24 hours. ISBN: 0-672-32224-2. Hour 21, chapter 'Inclusion and inclusion guards': 'It never hurts to use inclusion guards. Often they will save you hours of debugging time'. Also: hour 24, chapter 'include guards': 'All header files should use inclusion guards'.
- 11) Jesse Liberty. Sams teach yourself C++ in 24 hours. ISBN: 0-672-32224-2. Hour 24, chapter 'assert()': 'Use assert freely'.
[Edit this page] [Page history] [What links here] [Discuss this topic] [Printer Friendly]
