我不明白以下程序的输出:
#include <iostream>
#define FOO std::cout << __LINE__ << ' ' \
<< __LINE__ << '\n';
int main()
{
FOO
std::cout << __LINE__ << ' ' \
<< __LINE__ << '\n';
}
第一个输出是7
和7
,表示FOO
的扩展是单个逻辑行,但第二个输出是9
和{{1} },表示两条不同的逻辑行。为什么会有区别?
答案 0 :(得分:5)
由于
1: #include <iostream>
2:
3: #define FOO std::cout << __LINE__ << ' ' \
4: << __LINE__ << '\n';
5: int main()
6: {
7: FOO // the first two __LINE__s come from here, that's one line of code
8:
9: std::cout << __LINE__ << ' ' \ // 3rd __LINE__ comes from here
10: << __LINE__ << '\n'; // 4th __LINE__ comes from here
11: }
__LINE__
扩展为物理线,而不是逻辑线:
当前源行的行号比将源文件处理为当前令牌时在转换阶段1(2.2)中读取或引入的换行符号数大1。 / p>
虽然以\
结尾的行在翻译阶段2中连接在一起。
另一个唯一的逻辑实现是打印3和4来调用FOO,但这似乎不太有用。
您还可以通过以下方式查看此内容:__LINE__
与任何其他宏没有任何不同。它只是由编译器在每一行的开头自动更新。所以代码就是这样解释的:
#include <iostream>
#define __LINE__ 3
#define FOO std::cout << __LINE__ << ' ' \
<< __LINE__ << '\n';
int main()
{
#define __LINE__ 7
FOO
#define __LINE__ 9
std::cout << __LINE__ << ' ' \ // Yeah, you're right
#define __LINE__ 10
<< __LINE__ << '\n';
}
这不是有效的代码,但它演示了这些工作原理。应用通常的宏扩展规则,你将得到你已经得到的输出。
答案 1 :(得分:3)
因为#define
扩展包含hackery以确保__LINE__
是“调用”宏的那个。否则,很多错误消息对用户没有意义。
答案 2 :(得分:2)
导致您在#define
语句中定义的一个总是被评估为一行。但是,第二种情况实际上是两行代码。
答案 3 :(得分:0)
替换Foo需要评估预定义指令_ _LINE _ _。据我所知,这是因为,没有第二个预处理过程来评估_ _LINE _ _。
因此_ _LINE _ _的评估基于Foo被扩展的行,即第7行。
在代码的后续行中_ _LINE _ _的使用实际上是在预处理阶段根据它在翻译单元的源代码中出现的确切行号进行评估。