C ++宏中相互引用的奇怪结果

Strange result from mutual reference in C++ macro

考虑以下 C++ 代码:

#include <bits/stdc++.h>
using namespace std;

string TRUE = "true";
string FALSE = "false";

#define TRUE FALSE
#define FALSE TRUE

int main()
{
    cout << TRUE << endl;
    cout << FALSE << endl;
}

使用GCC 4.9.2编译,以上代码输出:

true
false

产生的输出背后的逻辑是什么?我预计 "false\ntrue\n" 甚至 "false\nfalse\n",但我找不到此实际输出背后的原因。

在这种情况下,#defines 对如何工作?

这在 [cpp.rescan]/1-2:

中有描述

16.3.4 Rescanning and further replacement

  1. After all parameters in the replacement list have been substituted and # and ## processing has taken place, all placemarker preprocessing tokens are removed. Then the resulting preprocessing token sequence is rescanned, along with all subsequent preprocessing tokens of the source file, for more macro names to replace.
  2. If the name of the macro being replaced is found during this scan of the replacement list (not including the rest of the source file's preprocessing tokens), it is not replaced. Furthermore, if any nested replacements encounter the name of the macro being replaced, it is not replaced. These nonreplaced macro name preprocessing tokens are no longer available for further replacement even if they are later (re)examined in contexts in which that macro name preprocessing token would otherwise have been replaced.

(强调我的)

所以:代码中遇到TRUE时,用FALSE代替。重新扫描序列,FALSE 替换为 TRUE。重新扫描序列,发现 TRUE 但不再符合替换条件,因此它会保留下来。这同样适用于 FALSE 的扩展(使用交换标识符)。

宏不能递归:如果一个宏直接或间接扩展为包含它自己的名称,则第二次出现将不再扩展。因此,在您的情况下,会发生以下扩展:

输入:

cout << TRUE << endl;

TRUE是一个宏,展开后:

cout << FALSE << endl;

为宏重新扫描扩展文本,FALSE 找到并扩展:

cout << TRUE << endl;

重新扫描扩展文本以查找宏,找到 TRUE;但它已经被扩展过一次,所以什么也没有发生,它保持为 TRUE 以供后续编译(然后找到全局变量)。