2012-04-04 5 views
2

Ich arbeite mit Embedded-Gerät, mit 32K Speicher, Schreiben in Ebene C mit IAR EWARM v6.30.Hat das Definieren des Enum-Typs einen starken Speicherabdruck?

Um Code besser lesbar machen Ich möchte einige Aufzählungstypen definieren, zum Beispiel so etwas wie

{RIGHT_BUTTON, CENTER_BUTTON, LEFT_BUTTON} 

statt 0 zu verwenden, 1, 2 Werte, aber ich fürchte, es zusätzliche Speicher nehmen, dass ist schon knapp.

So habe ich 2 Fragen: 1) Kann ich erzwingen Enum zu kurz oder byte Typ intad von int? 2) Was ist ein exakter Speicherabdruck des definierenden Enum-Typs?

Antwort

6

In voller Übereinstimmung mit ISO C sind die Größe und der Typ einer Enum-Konstante signed int. Einige Embedded-System-Compiler erfüllen dies bewusst nicht als Optimierung oder Erweiterung.

In ISO C++ „Der zugrunde liegende Typ eines Aufzählungs ein integraler Typ ist, der alle Aufzählungswerte definiert in der Aufzählung darstellen kann.“, so ein Compiler frei ist die kleinstmögliche Art zu verwenden, und die meisten tun, sind aber nicht dazu verpflichtet.

In Ihrem Fall (IAR EWARM) heißt das Handbuch klar:

enter image description here

Keine Option ist erforderlich, in der Tat Sie --enum_is_int verwenden müssen, würde konformes Verhalten zu erzwingen. Andere Compiler können sich anders verhalten oder verschiedene Erweiterungen, Pragmas oder Optionen haben, um dies zu kontrollieren. Solche Dinge werden normalerweise in der Dokumentation definiert.

+0

Vielen Dank, ich hatte nicht das Handbuch handlich – Flot2011

+0

@ Flot2011: Wirklich !? Das ist das Internet; Das Handbuch ist immer praktisch! [* Ich * habe es heruntergeladen] (http://www.iar.com/en/Products/IAR-Embedded-Workbench/ARM/User-guides/). Ich habe nicht den Compiler, aber ich würde mir vorstellen, nachdem ich andere IAR-Produkte in der Vergangenheit verwendet habe, dass das Handbuch lokal installiert wird, wenn Sie die IDE installieren, und über das Hilfe-Menü in der einen oder anderen verfügbar ist (Hilfe oder PDF). – Clifford

+0

: OK, also willst du trotzdem eine Erklärung. Hier geht es: Ich arbeite überhaupt nicht mit diesem Compiler, ich arbeite mit VS2003 und mein Code wird später auf dem Client-Rechner neu kompiliert, weil der Client keine Lizenz für mich kaufen will :-(Ich hatte ein Test, der abgelaufen war und ich ihn deinstalliert habe Da ich nicht sicher war, welche Version des IAR der Client letztendlich verwenden wird, habe ich gedacht, dass ich besser eine allgemeine Frage stellen werde, aber eigentlich hast du recht, ich war hier ein bisschen faul Danke für die Antwort – Flot2011

1

Ein ANSI-C-Compiler stellt immer eine Enumeration als int dar, um Variablen vom Typ enum darzustellen.

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

Eine Option int s in Ihrem Programm verwenden würde, sie zu verwenden, um Werte zu definieren, aber zu char werfen, wenn sie tatsächlich

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

Ja, ich weiß es, ich hatte nur gehofft, dass es einen Compiler-Switch der Art gibt, um dieses Standardverhalten zu ändern. – Flot2011

+0

@ Flot2011: Hängt von Ihrem Compiler ab. Welchen Compiler benutzen Sie? –

+0

IAR für ARM, ver 6.30 – Flot2011

2

Wenn Sie wirklich die Datengröße halten müssen bis zu char dann können Sie immer eine Reihe von #define konstanten Werten verwenden, um die enum Zustände darzustellen und nur diese Werte in Ihren Zuweisungen und Tests zu verwenden.

2

Für einen übereinstimmenden Compiler ist eine Aufzählungskonstante immer vom Typ int (äquivalent signed int). Aber solche Konstanten werden normalerweise nicht im Speicher gespeichert, so dass ihr Typ wahrscheinlich keinen großen Einfluss auf die Speicheranforderungen hat.

Ein deklariertes Objekt des Aufzählungstyps ist vom Aufzählungstyp selbst, der mit char oder mit einem Vorzeichen vom Typ mit oder ohne Vorzeichen kompatibel ist. Die Wahl des Typs ist implementationsdefiniert (d. H. Der Compiler wird wählen müssen, aber er muss dokumentieren, wie er die Wahl trifft); Die einzige Voraussetzung ist, dass der Typ in der Lage sein muss, die Werte aller Konstanten zu speichern.

Es ist zugegebenermaßen seltsam, dass die Konstanten vom Typ int und nicht vom Aufzählungstyp sind, aber so ist die Sprache definiert (die Gründe sind historisch und C++ hat andere Regeln).

Zum Beispiel gegeben:

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

der Ausdruck z vom Typ int und hat den Wert 2 (ebenso wie der Dezimalkonstante 2), sondern das Objekt obj ist vom Typ enum foo und kann so klein sein, als ein Byte, abhängig vom Compiler. Die Zuweisung obj = z; beinhaltet eine implizite Konvertierung von int zu enum foo (diese Konvertierung kann zusätzlichen Code erfordern oder nicht erfordern).

Einige Compiler bieten möglicherweise eine nicht standardmäßige Möglichkeit, den für einen Aufzählungstyp zu wählenden Typ anzugeben. Einige können sogar den Standard in irgendeiner Weise verletzen. Sehen Sie in der Dokumentation Ihres Compilers nach, drucken Sie den Wert sizeof (enum foo) aus und untersuchen Sie gegebenenfalls den generierten Code.

Es ist wahrscheinlich, dass Ihr Compiler innerhalb der von der Sprache vorgegebenen Einschränkungen vernünftige Entscheidungen treffen wird. Für einen Compiler, der auf speicherarme eingebettete Systeme ausgerichtet ist, ist es besonders wahrscheinlich, dass der Compiler entweder einen kleinen Typ auswählt oder Sie einen angeben lässt. Konsultieren Sie die Dokumentation Ihres Compilers.

Wie Ians Antwort darauf hinweist, können Sie, wenn Sie die Speichernutzung selbst steuern möchten, char oder unsigned char Objekte verwenden. Sie können jedoch weiterhin eine enum Definition verwenden, um die Konstanten zu definieren. Zum Beispiel:

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; 

Verweis: Abschnitt 6.7.2.2 der C standard. Der Link ist zu einem 1,7-Megabyte-PDF eines kürzlich veröffentlichten Entwurfs des ISO-C-Standards 2011; Dieser spezielle Abschnitt hat sich seit 1989 nicht wesentlich verändert.

+0

Dies ist die richtige Antwort für C. Ich kann überprüfen, dass sich der Standardtext zwischen dem C11-Entwurf und dem offiziellen C11-Standard auch nicht geändert hat. – Lundin

Verwandte Themen