これによるとSO投稿:
Cでの列挙型のサイズはいくつですか?
列挙型にはsigned int
型があります。
列挙型の定義をsigned int
からunsigned int
に変換したいと思います。
たとえば、私のプラットフォームでは、unsigned int
は32ビット幅です。列挙型を作成したい:
typedef enum hardware_register_e
{
REGISTER_STATUS_BIT = (1U << 31U)
} My_Register_Bits_t;
私のコンパイラは、上記の定義が範囲外であると文句を言っています(これはsigned int
用です)。
unsigned int
enum
値を宣言するにはどうすればよいですか?
残念ながら、ISO C標準(c99 6.4.4.3)では、列挙定数のタイプはint
であると規定されています。上記を例えばでコンパイルした場合gcc -W -std=c89 -pedantic
、警告ISO C restricts enumerator values to range of ‘int’ [-pedantic]
を発行します。一部の組み込みコンパイラは、コードをまったく受け入れない場合があります。
コンパイラの種類が多い場合は、次を使用して問題を回避できます。
typedef enum hardware_register_e
{
REGISTER_STATUS_BIT = -2147483648 /* 1<<31, for 32-bit two's complement integers */
} hardware_register_t;
ただし、int
がアーキテクチャ上の32ビット2の補数型である場合にのみ正しく機能します。これは、私が今まで使用または聞いたことのあるすべての32ビットおよび64ビットアーキテクチャにあります。
追加のために編集:ARM7は32ビット2の補数int
型を使用するため、上記は正常に機能するはずです。実際の値は1<<31
であることを説明するコメントを保持することをお勧めします。誰かがコードを移植したのか、別のコンパイラを使用したのかはわかりません。新しいコンパイラが警告を発した場合、同じ行のコメントで修正するのは簡単です。個人的には、コードを条件付きでラップします。
typedef enum hardware_register_e
{
#ifdef __ICCARM__
REGISTER_STATUS_BIT = -2147483648 /* 1<<31, for 32-bit two's complement integers */
#else
REGISTER_STATUS_BIT = 1 << 31
#endif
} hardware_register_t;
これによるとSO post:Cの列挙型のサイズはどれくらいですか?列挙型はint型に署名しています。
enum
型canはint
型ですが、Cではint
ではありません。 gcc
に 1)、enum
タイプはデフォルトでunsigned int
です。
enum
定数はint
ですが、enum
タイプは実装で定義されています。
あなたの場合、enum
定数はint
ですが、int
に収まらない値を指定しています。 Cがenum
であると言っているので、Cにunsigned int
int
定数を含めることはできません。
コンパイラに列挙型を符号なしにするオプションまたはプラグマがあるかどうかを確認してください。そうでない場合は、列挙型の代わりにプレーンなunsigned int
(またはuint32_t
などの固定幅タイプ)を使用し、#define
sを使用して定義する必要があります。それが取ることができる値。
列挙型のタイプを(少なくとも移植可能に)変更することはできません。標準では、列挙定数の型がint
であることは明らかです。警告を取り除くには、キャストを使用できます。
typedef enum hardware_register_e
{
REGISTER_STATUS_BIT = (int)(1U << 31U)
} My_Register_Bits_t;
可能な代替案
これをヘッダーに含める必要がない場合は、列挙定数の代わりに、必要なタイプのconst
オブジェクトを使用できます。
const unsigned int REGISTER_STATUS_BIT = (1U << 31);
それ以外の場合は、次の定義を使用できます。
#define REGISTER_STATUS_BIT (1U << 31)