造成此问题的原因是您试图混合在代码处理的不同阶段考虑的信息。
宏和所有 CPP(C 预处理器)内容发生在其他任何事情之前(正如其名称所示)。它对变量值一无所知(最多是#define),它所做的大部分工作都是文本整理。
某些变量值可能在编译时已知(请参阅constexpr https://en.cppreference.com/w/cpp/language/constexpr) ...但大多数只有在运行时才会知道。
因此,总而言之,您的代码失败是因为预处理器对id
多变的。
编辑:解释总和示例。
我们有这个代码x.cpp
#define sum(a,b) a + b
int main(int argc, char **argv) {
int x = 1, y = 2;
return sum(x,y);
}
这段代码编译并运行良好。
让我们看看幕后发生了什么。
所有 C/C++ 源文件都是预处理的。这意味着它们使用与 C 或 C++ 不同的语言进行评估:CPP(C 预处理器)。这个 CPP 负责所有 #... 的内容(例如搜索和包含头文件),正如我所说,与 C 或 C++ 无关。
事实上,您甚至可以在没有编译器的情况下运行它(尝试cpp x.cpp
)或者您可以指示编译器仅执行此阶段(g++ -o x.i -E x.cpp
)
如果我们研究 x.i:
# 1 "x.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "x.cpp"
int main(int argc, char **argv) {
int x = 1, y = 2;
return x + y;
}
我们可以观察到几件事:
- 还有许多附加的“#”行。编译器使用它们来跟踪所有内容的来源以及所包含位的来源,以便能够提供有意义的错误消息。
- 请注意代码中的 sum 宏是如何被替换的。这是盲目完成的,结果字符串是不正确的 C/C++ 语法,它还不会被检测到,但只有在实际的 C/C++ 解析完成时才会被检测到。