c++ - 如何在传递给 C/C++ 宏之前解析 int 变量?

标签 c++ c-preprocessor

我正在尝试执行以下代码:

#define channel1 10
#define channel(id) channel##id

int main(){
    int id = 1;
    cout << channel(id)<<"\n";

    return 0;
}

我收到以下错误: 错误:使用未声明的标识符“channelid”

相反,我希望输出为 10,因为应该将 channel(id) 预处理为 channel1 并将值替换为10.

有什么方法可以实现吗?

最佳答案

问题是因为您试图混合在代码处理的不同阶段考虑的信息。

宏和所有 CPP (C-Pre-Processor) 的东西在其他任何事情之前发生(正如它自己的名字所示)。它对变量值一无所知(最多是关于#define),而且它所做的大部分工作都是文本处理。

一些变量值可能在编译时已知(参见 constexpr)...但其中大部分只有在运行时才知道。

因此,总而言之,您的代码失败了,因为预处理器对 id 变量一无所知。

编辑:解释 sum 示例。

我们有这个代码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;

}

我们可以观察到几件事:

  1. 还有许多额外的“#”行。编译器使用这些来跟踪所有内容的来源以及所包含位的来源,以便能够提供有意义的错误消息。
  2. 请注意我们的 sum 宏是如何在代码中被替换的。这是盲目完成的,结果字符串被证明是不正确的 C/C++ 语法,它不会被检测到,但只有在实际的 C/C++ 解析完成时才会被检测到。

关于c++ - 如何在传递给 C/C++ 宏之前解析 int 变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54972468/

相关文章:

c++ - 在x64模式下从C++/CLI调用MASM PROC会产生意外的性能问题

c++ - OpenCv 和 Visual C++ 人脸检测

c++ - 基于 L 或 R 值模板的成员变量类型

c++ - 我们不使用双数组是什么?

c++ - 为什么投不成功?

c++ - 将两个#define 混合成一个词

c - 是否可以从头文件输出变量?

c++ - 数组初始化宏

c - 根据宏中的条件选择结构成员

c++ - 保存 C++ 预处理器宏的原始值