C言語における列挙型(enum)は、一連の整数の名前付き定数を定義する方法です。典型的な構文は次のとおりです:
enum Color { RED, GREEN, BLUE };
デフォルトでは最初の値に0が割り当てられ、各次の値には前の値に1を加えたものが割り当てられます。
列挙型の利点:
弱点:
int型(C99以前)であり、型の厳密な安全性がありません。enumとint間の暗黙の変換(範囲の制御がありません)。enum MyType : unsigned charで可能ですが、これは拡張です)。例:
enum State { INIT = -1, RUNNING = 0, PAUSED = 1, STOPPED = 2 }; enum State current = RUNNING;
質問: 異なる列挙型の値を安全に比較できますか?
答え: 技術的にはenumの値はintであるため、異なる列挙型の変数を比較することは望ましくありません。これは意味の喪失を引き起こし、読み手を混乱させる可能性があり、将来的にコードの保守が複雑になります。型を明示的に変換するか、論理的に列挙型を再グループ化する方が良いでしょう。
エラーの例:
enum Fruit { APPLE, BANANA }; enum Animal { CAT, DOG }; if ((enum Fruit)BANANA == (enum Animal)CAT) { ... } // 論理エラー
歴史
プロセス間通信プロトコルでは、非一意の名前の#defineに制限され、プロトコルの拡張時に値の衝突が発生しました。enumへの移行により、使用されるIDの管理が簡素化され、デバッグが容易になりました。
歴史
大規模なライブラリでは、状態の処理が整数のハードコーディングされた値に依存していました。リファクタリングの際に、新しい値にすべてのdefineを同期するのを忘れました。enumの使用によりこれを防ぐことができましたが、一部のモジュールが古いdefineを使用し続け、発見が難しいエラーを引き起こしました。
歴史
ロボットノードを管理するシステムでは、技術者がenumの最初の要素の値を明示的に設定しませんでした(2番目と3番目のみが使用されました)。プログラムは正しく動作せず、デフォルトで最初の要素が0の値を持っていて、期待される異なる値とプロトコルのロジックが衝突しました。