简体   繁体   中英

Macros argument evaluation in C++

I don't understand what is the reason that macros don't evaluate their argument only once (like inline functions), but each time it is used in the code.

For example:

(the example is taken from here: https://docs.microsoft.com/en-us/cpp/cpp/inline-functions-cpp?view=msvc-170 )

In this code there is a macro:


// inline_functions_macro.c
#include <stdio.h>
#include <conio.h>

#define toupper(a) ((a) >= 'a' && ((a) <= 'z') ? ((a)-('a'-'A')):(a))

int main() {
   char ch;
   printf_s("Enter a character: ");
   ch = toupper( getc(stdin) );
   printf_s( "%c", ch );
}
//  Sample Input:  xyz
// Sample Output:  Z


Compared to this code, with the equivalent inline function:

// inline_functions_inline.cpp
#include <stdio.h>
#include <conio.h>

inline char toupper( char a ) {
   return ((a >= 'a' && a <= 'z') ? a-('a'-'A') : a );
}

int main() {
   printf_s("Enter a character: ");
   char ch = toupper( getc(stdin) );
   printf_s( "%c", ch );
}

Macros are not very smart. They simply perform text substitution before compilation begins.

The code:

#define toupper(a) ((a) >= 'a' && ((a) <= 'z') ? ((a)-('a'-'A')):(a))

int main() {
   char ch = toupper( getc(stdin) );
}

Instructs the preprocessor to change this code and instead hand this to the compiler:

int main() {
   char ch = ((getc(stdin)) >= 'a' && ((getc(stdin)) <= 'z') ? ((getc(stdin))-('a'-'A')):(getc(stdin)));
}

You can observe that toupper was replaced by the defined expression, while every occurance of a is replaced by whatever text was passed as the macro parameter. It's not a value or an expression - it's just text.

Asde from the problems you observe, you may also discover that compiler errors will show this substituted code. Code that you don't see in your source file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM