替换__LINE__宏

msc*_*msc 0 c c++ macros

我使用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;
}
Run Code Online (Sandbox Code Playgroud)

输出:

20
Run Code Online (Sandbox Code Playgroud)

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

Sto*_*ica 9

如果要打印,10则更改L为非宏的内容:

constexpr int L = __LINE__;
Run Code Online (Sandbox Code Playgroud)

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

int i = __LINE__;
Run Code Online (Sandbox Code Playgroud)

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

回想一下,宏执行令牌替换.当你#define L __LINE__只指定当它出现在源中时应该替换什么标记L.在L自己的定义中,它不能替代任何东西.

C++ - [cpp.replace]/9C - [6.10.3宏替换]/9

表单的预处理指令

# define identifier replacement-list new-line
Run Code Online (Sandbox Code Playgroud)

定义一个类似于对象的宏,它使宏名称的每个后续实例都被构成指令其余部分的预处理标记的替换列表替换.然后重新扫描替换列表以获取更多宏名称,如下所示.


n. *_* m. 5

  #define y 42
  #define x y
Run Code Online (Sandbox Code Playgroud)

这使得x定义为包含一个令牌的预处理令牌序列y.不是令牌42.

  cout << x;
Run Code Online (Sandbox Code Playgroud)

这将expad xy随后 y42.

#undef y
#define y "oops"
Run Code Online (Sandbox Code Playgroud)

x仍被定义为y.

cout << x;
Run Code Online (Sandbox Code Playgroud)

你猜猜会发生什么.__LINE__在这方面并不特别.