__COUNTER__ プリプロセッサ マクロを使用したことのある人はいますか?

__COUNTER__ 一意の名前が必要な場合に便利です。私はこれを RAII スタイルのロックとスタックに広く使用してきました。考慮事項:

struct TLock
{
  void Lock();
  void Unlock();
}
g_Lock1, g_Lock2;

struct TLockUse
{
  TLockUse( TLock &lock ):m_Lock(lock){ m_Lock.Lock(); }
  ~TLockUse(){ m_Lock.Unlock(); }

  TLock &m_Lock;
};

void DoSomething()
{
  TLockUse lock_use1( g_Lock1 );
  TLockUse lock_use2( g_Lock2 );
  // ...
}

ロックの使用に名前を付けるのは面倒です。ブロックの先頭ですべて宣言されていないと、エラーの原因になることさえあります。 lock_use4 にいるかどうかはどうやってわかりますか または lock_use11 ?これは、名前空間の不必要な汚染でもあります。ロック使用オブジェクトを名前で参照する必要はありません。だから私は __COUNTER__ を使います :

#define CONCAT_IMPL( x, y ) x##y
#define MACRO_CONCAT( x, y ) CONCAT_IMPL( x, y )
#define USE_LOCK( lock ) TLockUse MACRO_CONCAT( LockUse, __COUNTER__ )( lock )

void DoSomething2()
{
  USE_LOCK( g_Lock1 );
  USE_LOCK( g_Lock2 );
  // ...
}

しかし、私がオブジェクト ロックを呼び出したという事実にとらわれないでください。一致するペアで呼び出される必要があるすべての関数は、このパターンに適合します。特定のブロックで同じ「ロック」を複数回使用することもできます。


DEBUG マクロ以外には使用したことがありません。言えると便利です

#define WAYPOINT \
    do { if(dbg) printf("At marker: %d\n", __COUNTER__); } while(0);

コンパイル時のアサーション マクロで使用して、マクロに一意の typedef の名前を作成させました。

を参照してください
  • C でビルド時に式をアサートする方法

血みどろの詳細が必要な場合。