2012-04-04 6 views
2

私はIARのEWARMのバージョン6.30を使用して、プレーンCに書き込み、メモリの32Kで、組み込みデバイスで働いています。は定義列挙型が重いメモリインプリントを持っていますか?

コードを読みやすくするために、私は、例えば、代わりに0を使用しての

{RIGHT_BUTTON, CENTER_BUTTON, LEFT_BUTTON} 

のようなものをいくつか列挙型を定義したい1、2つの値が、私はそれが追加のメモリがかかります怖いですすでに不足しています。

だから私は2つの質問があります: 1)私はint型の短いまたはバイト型inteadであると列挙型を強制することはできますか? 2)列挙型を定義するの正確なメモリインプリントとは何ですか?

答えて

6

完全に準拠ISO Cに列挙定数の大きさと種類はsigned intのものです。一部の組み込みシステムコンパイラは、意図的に最適化または拡張としてそれに準拠していません。 ISO C++では

列挙の基になる型が列挙で定義されているすべての列挙子の値を表すことができ整数型です。」、そう、コンパイラは可能な限り最小の型を使用して自由であり、ほとんどが行いますそうする必要はありません。あなたのケース(IAR EWARM)で

、マニュアルでは、明確に述べていない:

enter image description here

オプションなし必要が、実際にあなたが準拠の動作を強制的に--enum_is_intを使用する必要があるだろう。他のコンパイラは、動作を異ならせたり、これを制御するための拡張子、プラグマ、オプションを異ならせることがあります。そのようなことは、通常、ドキュメンテーションで定義されます。適合コンパイラ

+0

ありがとう、私はマニュアルを手元に持っていなかった – Flot2011

+0

@ Flot2011:本当に!これはインターネットです。マニュアルは常に便利です! [*私はそれをダウンロードしました](http://www.iar.com/en/Products/IAR-Embedded-Workbench/ARM/User-guides/)。私はコンパイラを持っていませんが、以前は他のIAR製品を使用していたので、IDEをインストールするときにマニュアルがローカルにインストールされ、ヘルプメニューから利用できますPDF)。 – Clifford

+0

:OK、とにかく説明が必要です。ここでは、私はこのコンパイラではまったく動作しません。私はVS2003で作業しています。クライアントは私のライセンスを購入したくないので、後でクライアントのマシンで再コンパイルします。 IARのどのバージョンが最終的に使用されるかわからなかったので、私は一般的な質問をよくすると思っていましたが、実際にはあなたは正しいです、私はここで少し怠惰でした。 – Flot2011

1

ANSI Cコンパイラは、enumの変数を表すintとして常に列挙型を表します。あなたのプログラムでint Sを使用する

http://en.wikipedia.org/wiki/Enumerated_type#C_and_syntactically_similar_languages

1つのオプションは、値を定義するためにそれらを使用することができますが、実際にデータのサイズを維持する必要がある場合は、実際に

char value = (char)Buttons.RIGHT_BUTTON; 
+0

はい、私はそれを知っています、私はちょうどこのデフォルトの動作を変更する種類のコンパイラスイッチがあることを望んでいました。 – Flot2011

+0

@ Flot2011:コンパイラによって異なります。どのコンパイラを使用しますか? –

+0

IAR for ARM、ver 6.30 – Flot2011

2

を使用する場合charにキャストしますcharまで、あなたは常にあなたの割り当てとテストでこれらの値を使用するしかenumの状態を表すために#define定数値のセットを使用してすることができます。

2

、列挙定数は常にタイプint(等価的に、signed int)のです。しかし、そのような定数は通常メモリに格納されないので、メモリの種類にはあまり影響しません。

列挙型の宣言されたオブジェクトは、列挙型自体であり、charまたは符号付きまたは符号なし整数型と互換性があります。型の選択は実装定義です(つまり、コンパイラが選択しますが、どのようにして選択するのかを文書化する必要があります)。唯一の要件は、型がすべての定数の値を格納できる必要があるということです。

定数が列挙型ではなくintであることは間違いですが、それは言語がどのように定義されているかです(理由は歴史的で、C++には異なる規則があります)。例えば

、所与:

enum foo { x, y, z }; 
enum foo obj; 
obj = z; 

発現zintであり、(ちょうど小数点定数2等)の値2を有しているが、オブジェクトobjenum fooであり、小さくてもよいです1バイトとして、コンパイラによって異なります。割り当てobj = z;には、intからenum fooへの暗黙的な変換が含まれます(変換には追加のコードが必要な場合もあります)。

一部のコンパイラでは、列挙型に選択する型を指定するための標準的ではない方法があります。何人かは標準に違反することさえあるかもしれません。コンパイラのドキュメントを参照してsizeof (enum foo)の値を出力し、必要に応じて生成されたコードを調べます。

コンパイラは、言語によって課せられた制約内で合理的な決定を下す可能性があります。メモリが不足している組み込みシステムを対象としたコンパイラでは、特にコンパイラが小さな型を選択するか、指定することができます。コンパイラのドキュメントを参照してください。

Ianの答えによると、メモリの使用量を自分で制御する場合は、charまたはunsigned charのオブジェクトを使用できます。ただし、定数を定義するのにまだenumの定義を使用できます。たとえば、

enum { x, y, z }; // No tag, so you can't declare objects of this type 
typedef unsigned char foo; // an enum_foo object is guaranteed to be 1 byte 
foo obj = z; 

参照:C standardのセクション6.7.2.2を参照してください。このリンクは、2011年のISO C標準の最近のドラフトの1.7メガバイトのPDFへのリンクです。この特定のセクションは1989年以来大きく変化していません。

+0

これはCの正解です。標準テキストがC11ドラフトと公式C11標準のどちらでも変更されていないことを確認できます。 – Lundin

関連する問題