Closed. This question needs details or clarity. It is not currently accepting answers. Learn more
想改进这个问题吗?添加细节并通过editing this post澄清问题。
去年关门了。
我正在尝试执行以下代码:
#define channel1 10
#define channel(id) channel##id

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

    return 0;
}

我得到以下错误:
error: use of undeclared identifier 'channelid'
相反,我希望输出为10,因为channel(id)应该被预处理为channel1,它将值替换为10。
有什么办法可以实现吗?

最佳答案

这是因为您试图混合在代码处理的不同阶段考虑的信息。
宏和所有CPP(C-Pre-Processor)的事情都发生在其他事情之前(正如它自己的名字所示)。它对变量值一无所知(最多只知道define),而且它所做的大部分工作都是文本争用。
某些变量值可能在编译时已知(请参见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++解析完成。

10-08 15:18
查看更多