yohhoyの日記

技術的メモをしていきたい日記

__COUNTER__マクロ

C/C++プリプロセッサにおいて、一意な識別子名生成に利用できる__COUNTER__マクロについて。非標準機能だが主要コンパイラで一通りサポートされている。

2024-09-26追記:C2y向けWG14提案文書 N3190 にて、C++2c向けWG21提案文書 P3384 にて__COUNTER__マクロの標準化が提案されている。

#define CAT_IMPL(s1, s2) s1##s2
#define CAT(s1, s2) CAT_IMPL(s1, s2)

#ifdef __COUNTER__
#define GEN_ID(str) CAT(str, __COUNTER__)
#else
#define GEN_ID(str) CAT(str, __LINE__)
#endif

// 識別子生成: 変数"foo1"などが生成される
auto GEN_ID(foo) = /*...*/;

Visual C++

Visual Studio .NET 2003(MSVC7.1)以降で利用可能。

Expands to an integer starting with 0 and incrementing by 1 every time it is used in a compiland. __COUNTER__ remembers its state when using precompiled headers. If the last __COUNTER__ value was 4 after building a precompiled header (PCH), it will start with 5 on each PCH use.
__COUNTER__ lets you generate unique variable names. You can use token pasting with a prefix to make a unique name.

http://msdn.microsoft.com/ja-jp/library/b0084kay%28v=vs.71%29.aspx

gcc

gcc 4.3以降で利用可能。

C family

  • A new predefined macro __COUNTER__ has been added. It expands to sequential integral values starting from 0. In conjunction with the ## operator, this provides a convenient means to generate unique identifiers.
http://gcc.gnu.org/gcc-4.3/changes.html