エラー、バグ、質問 - ページ 2866

 

すべて可能、必要なのは1つのマクロのみ

#define  VALUE 10

MACRO( VALUE, VALUE2 )

#define  VALUE   VALUE2*2

void f( int i = VALUE ) { Print( i ); }
void OnStart()
{
        f();
}

結果:20

 
A100:

すべて可能、必要なのは1つのマクロのみ

結果:20.

それはとても良いことです。パズルを当てるのは苦手なんです。

 
Vladimir Simakov:

すみません、説明してるうちに混乱してしまいました)))

もう1度

2回目のVALUE定義の時点では、VALUEマクロは定義されていないので、VALUEは次のように定義されます。

なぜなら、TMPは昔も今もVALUEで定義されているからです。

しかし、TMPは、2つ目のVALUEの定義の後、次のように展開される。

(こんな感じ))

プリプロセッサは持っているものを埋めるだけで、どこでどのように定義されているかは関係ないのです。だからこそ、気をつけなければならないことがあります。例

そして今度は、この関数に邪悪なもの、つまり副作用を追加してみましょう。

しかも、単なる銘板ですが、この機能に依存する預金ならどうでしょう?

ゲットしたら面白い)

#define  VALUE 10        
#define  TMP VALUE       
#undef  VALUE     

が正しく、置換を元に戻した後、1行目は10でなくなり、2行目のTMPはVALUEになりましたが、10ではありません。つまり、代入は代入とは程遠いのです。

 
Valeriy Yastremskiy:

ゲットすると面白い)

が正しく、置換を元に戻した後、1行目は10でなくなり、2行目のTMPはVALUEですが、10ではありません。つまり、代入は代入とは程遠いものなのです。

そう、置換はまさに一対一で置換されるのです。しかし、コード中にVALUEマクロが定義されている場合(プリプロセッサ指令と 混同しないように)、プリプロセッサはさらにTMP->VALUE->10と展開し、そうでなければTMP->VALUEと展開するのです。この場合、プリプロセッサー指示文はコード自体には関与せず、コンパイルされた時点で存在しなくなる。例

#define  VALUE 10
#define  TMP VALUE

void OnStart()
{
   Print(TMP); //10
if (false){
   #undef  VALUE
   #define  VALUE 20
   Print(TMP);}
else Print(TMP); //20
}
 
Vladimir Simakov:

そうです、代用はまさに代用、一対一です。単純に、VALUEマクロがコード内で定義されている場合(プリプロセッサ指令と 混同しないように)、プリプロセッサはTMP->VALUE->10と展開し、そうでない場合はTMP->VALUEとします。この場合、プリプロセッサー指示文はコード自体には関与せず、コンパイルされた時点で存在しなくなる。例

はい、2番目のVALUE代入20をコメントアウトすると、VALUE変数宣言がなくなり、コンパイラはそれを見ずに叱ることになります)

 
A100:

すべて可能、必要なのは1つのマクロのみ

結果:20

降参です)))

どのように定義されているのですか?

MACRO

?

 
Vladimir Simakov:

降参 です)))

どのように特定の

?

こんなに早く?まだ、すべてのスペシャリストが参加しているわけではありませんが...。1週間待ってみる。

ヒント:これも有効です(ただし、解決方法は若干異なります)

#define  VALUE1 10
#define  VALUE2 5

MACRO2( VALUE1, VALUE12 )
MACRO2( VALUE2, VALUE22 )

#define  VALUE1  VALUE12*2
#define  VALUE2  VALUE22*3

int f1( int i = VALUE1 ) { return i; }
int f2( int i = VALUE2 ) { return i; }
void OnStart()
{
        Print(f1(),":",f2());
}

結果:20:15

 
Vladimir Simakov:

なぜなら、TMPは昔も今も「VALUE」によって定義されているからです。

そこで、「トップダウン」の反論が登場する。

そうでなければ、TMPは「定義通りだから定義のまま」ではなく、以前は10に置き換えられていたはずである(VALUEはこれに置き換わる)。

つまり、プリプロセッサはコードを一行ずつ処理しているわけではないのです。あとは、どうすればいいのか。


@A100 さん、差し支えなければ、一言で言うと。
ググって読むほど面白くはないが、聞くには十分。

私の論理のどこがおかしいのでしょうか。

弦楽器を順次解析していくイメージです。だから、右側に未定義の値はない。

#define  VALUE 10       // VALUE = 10
#define  TMP VALUE      // TMP = 10
#undef  VALUE           // VALUE = EMPTY
#define  VALUE (TMP*2)  // TMP = 10, следовательно VALUE = 20
 
A100:

ヒント:これも有効です(ただし、解決方法は若干異なります)

そのため、MACROやMACRO2と動作が同じです。

 
Andrey Khatimlianskii:

私の論理のどこがおかしいのでしょうか。

#define  VALUE 10       // VALUE = 10
#define  TMP VALUE      // TMP = 10 VALUE
#undef  VALUE           // VALUE = EMPTY
#define  VALUE (TMP*2)  // TMP = 10 EMPTY, следовательно VALUE = 20 EMPTY