2017-11-29 27 views
0

Cppreferenceを使ってマクロについて読んだことがあります。__LINE__マクロを置き換える

__LINE__:ソースファイルの行数、整数定数に展開され、Iマクロ__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でないのですか?

+2

[C DR 483](http://www.open-std.org/JTC1/SC22/WG14/www/docs/summary.htm#dr_483) – cpplearner

+0

TL; DR:マクロは展開されません定義された。それが使用されるたびに(そしてどこで)展開されます。 – lockcmpxchg8b

+0

@ lockcmpxchg8b - これは悪いTLです; DR。 OPの混乱は、少なくともそれに直面して、 '#define L __LINE__' *が*' __LINE__'を使用することです。 – StoryTeller

答えて

9

あなたはマクロではない何かにLを変更後、10を印刷する場合:

constexpr int L = __LINE__; 

そうでないマクロLがラインint i = L;に置換してなることでしょう。

int i = __LINE__; 

行番号をもう一度代入して、最後の#line指令を読んでください。

マクロはトークンの置換を実行することを思い出してください。 #define L __LINE__の場合、のトークンLである必要があります。それはL自身の定義の時点で何かを置き換えるものではありません。

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

形態

# define identifier replacement-list new-line 

の前処理指令は マクロ名の後続の各インスタンスは、の置換リストに置き換えさせるオブジェクトようなマクロを定義しますディレクティブの残りの部分を構成するトークンを前処理する トークン。交換用の リストは、次に指定されたより多くのマクロ名に対して再スキャンされます。に値を変更するプリプロセッサディレクティブの後、マクロが展開され

#line 20 

使用(定義されていない場合)あなたのmain()機能である:

3

あなた#lineプリプロセッサディレクティブは20に値を変更します20

+1

私は、誤解は、 '__LINE__'が' #define L __LINE__'で展開されると思っていたと思います。 – Justin

5
#define y 42 
    #define x y 

これは、1トークンyが含まれている前処理トークンのシーケンスとして定義xます。トークンではありません42

cout << x; 

これは42に、その後yからxyをexpadます。

#undef y 
#define y "oops" 

xはまだyとして定義されます。

cout << x; 

あなたは何が起こるか推測します。 __LINE__はこの点で特別ではありません。

関連する問題