これは、これまでのところ私が思いつくことができる最高のものです。動作しますが、実装はちょっとお粗末です。
使用法
あなたが書く場合:
STATIC_BLOCK {
std::cout << "Hello static block world!" << std::endl;
}
このコードは、main()
. ただし、開始std::cout
前に書き込むことmain()
は、実際にはそれほど優れたアイデアではないことに注意してください。
ノート:
- 静的ブロック コードを中かっこで囲む必要があります(末尾のセミコロンは必要ありません。@KlitosKyriacou の提案に感謝します)。
- 中括弧を使用しない場合は、わかりにくいエラー メッセージが表示されます。
- C++ では、静的コードの相対的な実行順序は保証されません。
実装
静的ブロックの実装には、ダミー変数が含まれます。他のダミー変数 (たとえば、別の静的ブロックまたはその他の場所) と衝突しないようにするために、マクロ機構が少し必要です。
#define CONCATENATE(s1, s2) s1##s2
#define EXPAND_THEN_CONCATENATE(s1, s2) CONCATENATE(s1, s2)
#define STATIC_BLOCK_IMPL2(function_name,var_name) \
static void function_name(); \
static int var_name __attribute((unused)) = (function_name(), 0) ; \
static void function_name()
#define STATIC_BLOCK_IMPL1(prefix) \
STATIC_BLOCK_IMPL2(CONCATENATE_FOR_STATIC_BLOCK(prefix,_fn),CONCATENATE_FOR_STATIC_BLOCK(prefix,_var))
#define STATIC_BLOCK STATIC_BLOCK_IMPL1(EXPAND_THEN_CONCATENATE(static_block_,__COUNTER__))
ノート:
- コンパイラがサポートしていない場合
__COUNTER__
(標準の一部ではなく標準の拡張であるため) __LINE__
、 を使用できます。これも機能します。GCC と Clang のサポート__COUNTER__
。
__attribute__((unused))
属性は言語に組み込まれていますが、別のコンパイラ拡張機能です。たとえば、この議論を参照してください。ドロップすると警告が表示されます。
- コードは C++98 (コンパイラの拡張機能を無視) です。つまり、最新の C++ コンストラクトをサポートする必要はありません。残念ながら、これは C とは見なされません (初期化子は定数でなければなりません)。
SCOPE_EXIT
元々は Andrei Alexandrescu のトリックに触発されました。