【问题标题】:Replacing __LINE__ macro替换 __LINE__ 宏
【发布时间】:2018-05-12 23:02:34
【问题描述】:

我阅读了有关使用 Cppreference 的宏。

__LINE__:扩展为源文件行号,整数常量,可以通过#line指令改变

我制作了 c++ 程序来测试__LINE__ 宏。

#include <iostream>
using namespace std;

#line 10
#define L __LINE__

int main() 
{
    #line 20
    int i = L;
    cout<<i<<endl;
    return 0;
}

输出:

20

为什么上面代码的输出是20?为什么不是10?

【问题讨论】:

  • TL;DR:宏在定义时不会展开。每次使用它的时间(和地点)都会扩展。
  • @lockcmpxchg8b - 这是一个糟糕的 TL;DR。我认为 OP 的困惑在于,至少从表面上看,#define L __LINE__ uses __LINE__.

标签: c++ c macros


【解决方案1】:

如果您想打印10,请将L 更改为不是宏的内容:

constexpr int L = __LINE__;

否则 L 将被替换为int i = L; 并变为:

int i = __LINE__;

它必须再次替换行号,并读取最后一个#line 指令。

回想一下,宏执行令牌替换。当您#define L __LINE__ 时,它只指定L 出现在源代码中时应替换的tokens。在L 自己的定义点上,它不能替代任何东西。

C++ - [cpp.replace]/9C - [6.10.3 Macro replacement]/9

表单的预处理指令

# define identifier replacement-list new-line

定义了一个类似对象的宏,它会导致每个后续实例 被预处理的替换列表替换的宏名 构成指令其余部分的标记。替代品 然后重新扫描列表以获取更多如下指定的宏名称。

【讨论】:

    【解决方案2】:
      #define y 42
      #define x y
    

    这使得x 定义为一系列预处理标记,其中包含一个标记y。不是令牌42

      cout << x;
    

    这会将x 扩展为y然后 y 扩展为42

    #undef y
    #define y "oops"
    

    x 仍定义为y

    cout << x;
    

    你猜会发生什么。 __LINE__ 在这方面并不特殊。

    【讨论】:

      【解决方案3】:

      您的 #line 预处理器指令将值更改为 20

      #line 20
      

      在将值更改为 20 的预处理器指令之后,在您的 main() 函数中使用(未定义)的位置扩展宏。

      【讨论】:

      • 我认为误解是认为__LINE__ 将在#define L __LINE__ 处扩展,而不是在使用L 的位置。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-21
      • 1970-01-01
      • 2015-04-04
      • 1970-01-01
      • 2011-07-01
      • 1970-01-01
      • 2012-11-09
      相关资源
      最近更新 更多