DEV Community

dinhluanbmt
dinhluanbmt

Posted on • Edited on

C++, Preprocessor directives: #define, #ifdef...

Even though #define, #include, #ifdef, #ifndef, #endif.. are very common but when i try a hackerrank problem, the term "Preprocessor directives" sound unfamiliar to me. So i just summarize about it here.
Definition: Preprocessor directives are lines included in the code of programs preceded by a hash sign (#). These lines are not program statements but directives for the preprocessor. The preprocessor examines the code before actual compilation of code begins and resolves all these directives before any code is actually generated by regular statements
Some types of preprocessor directives that I frequently use :
Macro Definition

#define foreach(v,i) for(int i = 0; i< v.size();i++)
#define toStr(S) #S  // to string
#define getmax(a,b)  ((a) > (b)) ? (a): (b)
#define FUNCTION(name, operator) int name(int a, int b){if(a operator b)return a;else return b;}
FUNCTION(maximum, >)
FUNCTION(minimum, <)

void testFunc() {
    vector<int> iV = { 3,5,7,8,3,5,4 };
    foreach(iV, k) {
        cout << " " << iV[k];
    }
    cout << endl;
    int a = 9;
    int b = 52;
    int min_val = minimum(a, b);
    int max_val = getmax(a, b);
    cout << "Debug info : " << endl;
    cout << "  File : " << __FILE__ << endl;//predefined macro for debug
    cout<<"  Line : " << __LINE__ << endl;
    cout << endl;
    cout << toStr(Min Value = ) << min_val << endl;
    cout << toStr(Max Value = ) << max_val << endl;
}
Enter fullscreen mode Exit fullscreen mode

File Inclusion : #include "header.h"

Conditional Compilation

#define DEBUG 
void test_define() {
#ifdef DEBUG
    cout << "Debug mode enabled." << std::endl;
#else
    cout << " not define DEBUG " << endl;
#endif
#ifndef RELEASE
        cout << "Not in release mode." << std::endl;
#endif
}
Enter fullscreen mode Exit fullscreen mode

There are others directives like :

#undef
#pragma startup
#pragma exit
...
Enter fullscreen mode Exit fullscreen mode

but i never use except #pragma once to prevent multiple inclusions of the file

Top comments (3)

Collapse
 
pauljlucas profile image
Paul J. Lucas

Macro parameters should always be in parentheses:

#define MAX(a, b) ((a) > (b) ? (a) : (b))
Enter fullscreen mode Exit fullscreen mode

to prevent unintended expansions due to operator precedence.

There's a standard way to do debugging macros and it's:

#ifndef NDEBUG
Enter fullscreen mode Exit fullscreen mode

See assert() for details.

Your definition of foreach should be:

#define FOR_EACH(E,C) for ( auto const &E : (C) )
Enter fullscreen mode Exit fullscreen mode

but range-based for loops really eliminate the need for any such macro now.

Modern compilers really don't need #pragma once any more.

You completely ignore some of the more interesting things about the preprocessor.

Collapse
 
dinhluanbmt profile image
dinhluanbmt

thank you very much for your advice

Collapse
 
aregtech profile image
Artak Avetyan

Modern compilers really don't need #pragma once any more.

If you develop a library / framework, it is even better to use #ifndef ... #define ... #endif .... It guarantees that the same header in different location will be never included twice. In addition, developers can exclude obsolete / deprecated headers.