【问题标题】:Macros argument evaluation in C++C++ 中的宏参数求值
【发布时间】:2022-01-10 05:07:23
【问题描述】:

我不明白宏不只评估一次参数(如内联函数)而是每次在代码中使用的原因是什么。

例如:

(示例取自这里:https://docs.microsoft.com/en-us/cpp/cpp/inline-functions-cpp?view=msvc-170)

在这段代码中有一个宏:


// 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


与此代码相比,具有等效的内联函数:

// 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 );
}

【问题讨论】:

  • 宏是文本替换。它们不是函数。
  • 宏不是函数。它们是预处理器文本替换,仅此而已。不多也不少。就像您的源代码实际上具有由预处理器完成的替换文本,因此编译器抱怨每个宏的使用,而不是宏本身。
  • 一个重要的理解是宏是在编译之前展开的,也就是通常所说的“预处理阶段”。
  • 尝试使用以下参数扩展宏,“hello”和 3.1415269。这应该会告诉你为什么函数比宏更受欢迎。

标签: c++ macros inline


【解决方案1】:

宏不是很聪明。他们只是在编译开始前执行文本替换。

代码:

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

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

指示预处理器更改此代码并将其交给编译器:

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

您可以观察到toupper 被定义的表达式替换,而a 的每次出现都被作为宏参数传递的任何文本 替换。它不是一个值或表达式 - 它只是文本。

除了您观察到的问题外,您还可能会发现编译器错误会显示此替换代码。在源文件中看不到的代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-25
    相关资源
    最近更新 更多