問題の歴史:
マクロはC言語から来た強力な方法であり、プリプロセッサの段階で繰り返し行われるコードの自動化を実現します。C++での使用は柔軟性をもたらしましたが、型チェックがないため、多くの隠れた危険をもたらしました。
問題:
マクロ使用における主なリスクは:
解決策:
現代のC++標準では、マクロの代わりにインライン関数、テンプレート、constexpr、enum class、およびconstexpr変数の使用が推奨されています。
コード例:
// 悪い: #define MAX(a, b) ((a) > (b) ? (a) : (b)) // 良い: template<typename T> constexpr T max(T a, T b) { return a > b ? a : b; }
重要な特徴:
マクロはインライン関数よりも危険になることがありますか?
はい。マクロは構文や型の規則に従わないため、副作用を伴う引数を渡した際に予期しない結果が生じる可能性があります。
#define SQUARE(x) ((x) * (x)) int y = 5; int z = SQUARE(y++); // yが二回インクリメントされます!
#includeはマクロですか?
いいえ、#includeはプリプロセッサの指令ですが、マクロの使用とincludeは関連しており、マクロを通じてインクルードファイルのリストを変更することができます(これは極力推奨されません)。
マクロを通常の関数のようにデバッグできますか?
いいえ、デバッガはマクロを展開し、既に置き換えられたテキストを表示します。個別の名前付きエンティティは存在しません。
古いコードでは、効果を持つ多くの計算マクロが定義されており(例えば、インクリメント)、新機能の実装時に捉えにくいバグが発生しました。
メリット:
デメリット:
リファクタリングの際に、マクロはテンプレートやconstexpr関数に置き換えられ、enum classがフラグ用マクロの代わりに使用されました。
メリット:
デメリット: