新的 __LINE__ 何时开始?

发布于 2024-10-05 05:43:52 字数 433 浏览 0 评论 0原文

我不明白以下程序的输出:

#include <iostream>

#define FOO std::cout << __LINE__ << ' ' \
                      << __LINE__ << '\n';
int main()
{
    FOO

    std::cout << __LINE__ << ' ' \
              << __LINE__ << '\n';
}

第一个输出是77,表明FOO的扩展是单个逻辑行,但第二个输出是 910,表示两个不同的逻辑行。为什么会有差异?

I do not understand the output of the following program:

#include <iostream>

#define FOO std::cout << __LINE__ << ' ' \
                      << __LINE__ << '\n';
int main()
{
    FOO

    std::cout << __LINE__ << ' ' \
              << __LINE__ << '\n';
}

The first output is 7 and 7, indicating that the expansion of FOO is a single logical line, but the second output is 9 and 10, indicating two distinct logical lines. Why is there a difference?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

初懵 2024-10-12 05:43:52

因为

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';
}

这不是有效的代码,但它演示了事情是如何工作的。应用通常的宏扩展规则,您将得到您所得到的输出。

Because

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__ expands to physical lines, not logical lines:

The line number of the current source line is one greater than the number of new-line characters read or introduced in translation phase 1 (2.2) while processing the source file to the current token.

While the lines ended by \ are concatenated in translation phase 2.

The other only logical implementation would be to print 3 and 4 for the invocation of FOO, but that seems not very useful.

You can also look at this the following way: __LINE__ is not any different from any other macro. It's just updated automatically by the compiler at the beginning of every line. So the code is kind of interpreted this way:

#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';
}

This is not valid code, but it demonstrates how the things work. Apply the usual macro expansion rules and you'll get the output you've got.

一刻暧昧 2024-10-12 05:43:52

导致您在 #define 语句中定义的语句始终计算为一行。然而,第二种情况实际上是两行代码。

cause one you define in #define statement which always evaluated as one line. However, the second case is really two lines of code.

对不⑦ 2024-10-12 05:43:52

因为 #define 扩展包含黑客技术,以确保 __LINE__ 是“调用”宏的地方。否则很多错误消息对用户来说毫无意义。

Because #define expansion contains hackery to make sure __LINE__ is the one where the macro is "invoked". Otherwise a lot of error messages would make no sense to the user.

蝶…霜飞 2024-10-12 05:43:52

替换 Foo 需要评估预定义指令 __LINE __ 。据我了解,这是因为,没有第二个预处理过程来评估 __LINE __ 。

因此 _ _LINE _ _ 是根据 Foo 展开的行(即第 7 行)进行评估的。

代码中后续行中 _ _LINE __ 的使用实际上是在预处理阶段根据确切的行号进行评估的它出现在翻译单元的源代码中。

Substitution of Foo requires evaluation of the predefined directive _ _LINE _ _ . This as I understand is because, there is no second preprocessing pass to evaluate _ _LINE _ _ .

Hence the _ _LINE _ _ is evaluated based on the line on which Foo is being expaned which is Line 7.

The usage of _ _LINE _ _ in the subsequent line in your code is really evaluated during the preprocessing phase based on the exact line number it appears in the source code in the translation unit.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文