[c] sizeof(enum) bestimmen?

Gast #2265867
Lesenswert?

guten morgen allerseits..

ich spiele momentan ein wenig mit zustandsmaschinen herum..
dazu benötige ich zum einen ein enum, welches mir später die zustände 
als zahl ausdrückt, als auch eine funktionstabelle, welche so groß sein 
muss wie die anzahl der elemente im enum..
1
//the various states
2
#define NO_STATES  4
3
enum PWMStati{Idle,StartConversion,WaitConversion,CheckResults};
4

5
[..]
6

7
//Array of functions
8
static PWMstateControl func_array[NO_STATES] = {
9
  fIdle,
10
  fStartConversion,
11
  fWaitConversion,
12
  fCheckResults
13
};

allerdings kann das leicht zur stolperfalle werden, wenn man eine neue 
funktion einbaut, aber das NO_STATES nicht anpasst..
AVR_GCC hat mir zumindest nicht gemeldet, das mein NO_STATES um 1 zu 
klein war..

gibt es eine möglichkeit, die anzahl der "einträge" im enum per makro 
o.ä. zu bestimmen (sizeof geht nicht..?)


danke & mfg
Gast #2265873
Lesenswert?

Leider nicht.

In der Regel geht man hin und setzt als letztes Element der Aufzählung 
einen Zähler o.ä. hin:
1
enum State {
2
        State1,
3
        State2,
4
        State3,
5
        StateCount
6
};

Sofern man nun den Zuständen nicht händisch Werte verpasst, geht das so.
Gast #2265878
Lesenswert?

Ich weiß jetzt nicht, ob das astrein ist:
NO_STATES ans Ende der enum-Liste. Wenn das Erste bei '0' anfängt, ist 
dann NO_STATES die Anzahl. Wobei man sich wahrscheinlich bei
'static PWMstateControl func_array[NO_STATES]' was einfallen lassen 
muss, wegen des Datentypes!?
Gast #2265896
Lesenswert?

@Ralf:

ne, das schluckt der compiler nicht, obwohls ja schon irgendwie elegant 
wär..

aber der laufindex, den @Haku vorgeschlagen hat, ist für mich auch 
praktikabel.. muss man halt bei änderungen dran denken.. Oo

mfg
Gast #2265911
Lesenswert?

ach, ja, hast ja recht.. sry.. XD

für alle dies interessiert:
1
enum PWMStati{Idle,StartConversion,WaitConversion,CheckResults,NO_STATES};
2

3
[..]
4

5
static PWMstateControl func_array[(int)NO_STATES] = {
6
  fIdle,
7
  fStartConversion,
8
  fWaitConversion,
9
  fCheckResults
10
};
so frissts der compiler..

dankeschön.
#2265934
Lesenswert?

Läubi .. schrieb:
> dunno.. schrieb:
>> ne, das schluckt der compiler nicht, obwohls ja schon irgendwie elegant
>> wär..
>
> Was schluckt er nicht? Ein kleiner cast auf int kann den Compiler ggf.
> überzeugen, auch wenn es normalerweise nur eine Warnung geben sollte.

dunno.. schrieb:
1
 static PWMstateControl func_array[(int)NO_STATES] = {

Enum-Konstanten sind vom Typ int, wozu soll der Cast also gut sein?
#2266183
Lesenswert?

Peterle Anonym schrieb:
> sizeof liefert nicht die gesamtgröße wieder, sondern die größe eines
> elements, sprich eines INTs!

Bei meinem Beispiel? Definitiv nicht
C99 6.5.3.4
"When applied to an operand that has array type, the result is the total 
number of bytes in the array.85) When applied to an operand that has 
structure or union type, the result is the total number of bytes in such 
an object, including internal and trailing padding."
Moderator Persönliche Seite #2266303
Lesenswert?

Peterle Anonym schrieb:
> ohne Zitatvermerk bedeutet im Internet immer eine Antwort auf die
> Ausgangsfrage; da hat wohl jmd die Regeln geändert ohne mir bescheid zu
> sagen ;)

Ich sehe aber hier im Forum des öfteren Antworten ohne Zitate, die sich 
genau auf das letzte Posting darüber beziehen. Und wenn ich mir gerade 
Deine letzte Antwort ohne Zitat anschaue, hast Du gerade auf mein 
Posting und nicht auf die Frage des TO geantwortet.

Damit hast Du Dir gerade selbst widersprochen. q.e.d. ;-)
#2266317
Lesenswert?

Peterle Anonym schrieb:
> das war bezogen auf
>
> "gibt es eine möglichkeit, die anzahl der "einträge" im enum per makro
> o.ä. zu bestimmen (sizeof geht nicht..?)"
>
> klingt für mich nach sizeof(PWMStati)...
>
> und das liefert nunmal die größes eines elementes (int) wieder.

Zwar immer noch nicht elegant und nicht direkt "im enum", aber geht auch
1
#define EXPAND_VC(x) x
2
#define VA_NARGS_IMPL(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,N,...) N
3
#define VA_NARGS(...) EXPAND_VC(VA_NARGS_IMPL(__VA_ARGS__,10,9,8,7,6,5,4,3,2,1,0))
4

5
#define STATES sdf, aew, dert, itgl, sfgds
6

7
enum anEnum { STATES };
8
const int anEnumLength = VA_NARGS(STATES);


EXPAND_VC ist für den VC++, andere brauchen das nicht.
Die Idee geht wohl auf 
http://groups.google.com/group/comp.lang.c/browse_thread/thread/578912299f8f87ce#msg_937356effc43f569 
zurück und lässt sich erweitern
#2266337
Lesenswert?

Stimmt; eleganter geworden ist es nicht wirklich :-)

Aber wnen du jetzt noch etwas zauberst, daß parallel dazu ein Feld von 
char
* entsteht mit den Namen der enums für Debugausgaben ( = { "sdf", "aew", 
"dert", ... }), könnte ich mich damit anfreunden und wäre voll des Lobs!
#2266389
Lesenswert?

Klaus Wachtler schrieb:
> Stimmt; eleganter geworden ist es nicht wirklich :-)
>
> Aber wnen du jetzt noch etwas zauberst, daß parallel dazu ein Feld von
> char
> * entsteht mit den Namen der enums für Debugausgaben ( = { "sdf", "aew",
> "dert", ... }), könnte ich mich damit anfreunden und wäre voll des Lobs!
1
#define EXPAND_VC(x) x
2
#define VA_NARGS_IMPL(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,N,...) N
3
#define VA_NARGS(...) EXPAND_VC(VA_NARGS_IMPL(__VA_ARGS__,10,9,8,7,6,5,4,3,2,1,0))
4
#define ARGS_TO_STR_IMPL(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,...) "" #_1, "" #_2, "" #_3, "" #_4, "" #_5, "" #_6 ,"" #_7, "" #_8, "" #_9, "" #_10
5
#define ARGS_TO_STR(...) EXPAND_VC(ARGS_TO_STR_IMPL(__VA_ARGS__))
6

7
enum anEnum { STATES };
8
char* enumStr[] = { ARGS_TO_STR(STATES) };
9
const int enumLength = VA_NARGS(STATES);

reicht das
Gast #2266518
Lesenswert?

Ralf schrieb:
>> Aber wnen du jetzt noch etwas zauberst
> Also für mich ist das Zauberei :-)

hexerei!
- verbrennt ihn!


Arc Net schrieb:
> Zwar immer noch nicht elegant und nicht direkt "im enum", aber geht auch
> #define EXPAND_VC(x) x
> #define VA_NARGS_IMPL(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,N,...) N
> #define VA_NARGS(...) 
EXPAND_VC(VA_NARGS_IMPL(_VA_ARGS_,10,9,8,7,6,5,4,3,2,1,0))
>
> #define STATES sdf, aew, dert, itgl, sfgds
>
> enum anEnum { STATES };
> const int anEnumLength = VA_NARGS(STATES);

....

mh, das ding ist spannend.. sieht zum fürchten aus, und ist (für mich) 
nicht unbedingt auf einen blick zu erfassen, aber, spannend...

danke dir
Gast #2266579
Lesenswert?

dunno.. schrieb:
> sizeof geht nicht..?

sizeof () gibt den Speicherbedarf zurück, nicht den Wertebereich! Der 
Wertebereich richtet sich nach deiner eigenen Definition. Dein Ansatz 
mit dem define war der richtige.

Es ist m. E. in C nicht festgeschrieben, dass ein enum immer als Integer 
und immer beginnend von 0 gespeichert wird. Wobei die meisten Compiler 
es aber so machen.
#2266736
Lesenswert?

Ein vorbelegtes Array kann die [] leer lassen, dann wird die Länge 
automatisch ermittelt:
1
//the various states
2
enum PWMStati{Idle,StartConversion,WaitConversion,CheckResults};
3

4
//Array of functions
5
static PWMstateControl func_array[] = {
6
  fIdle,
7
  fStartConversion,
8
  fWaitConversion,
9
  fCheckResults
10
};
11

12
#define NO_STATES (sizeof(func_array) / sizeof(PWMstateControl))


Peter
Gast #2266768
Lesenswert?

Linker schrieb:
> Es ist m. E. in C nicht festgeschrieben, dass ein enum immer als Integer
> und immer beginnend von 0 gespeichert wird.

Der einem enum zugrundeliegende Typ ist immer ein Integer-Typ. Er muß 
nicht int sein, aber die Werte sind trotzdem immer vom Typ int. Und mit 
0 wird dann begonnen, wenn man nicht explizit was anderes hinschreibt.
Gast #2266794
Lesenswert?

Linker schrieb:
> Es ergibt die Anzahl in Byte,
ISO/IEC 9899:TC2 6.5.3.4, Abs. 2 und 3:
Ergebnis ist Größe in Bytes; char/unsigned char/signed char oder 
qualifizierte Ableitungen sind als '1' definiert.
Ich schrieb 'in Zeichen', weil Zeichen etwas schwierig ist, als dass es 
nicht unbedingt 8 Bits haben muss, sondern mehr haben darf (ISO/IEC 
9899:TC2 Annex E).


> die der Compiler zum Speichern des
> definierten enum benötigt. Bei vielen wird es int sein.
ISO/IEC 9899:TC2 6.7.2.2 Abs. 3:
Die Bezeichner der Aufzählung werden als int-Konstanten deklariert.

Die Aufzählung selber kann char oder vorzeichenbehafteter oder -loser 
int sein, sollte aber Platz für alle Konstanten bieten.
Gast #2266798
Lesenswert?

Peter Dannegger schrieb:
> Bei einem Enum wird garnichts gespeichert.
> Ein Enum ist wie ein Define nur ne Textersetzung.

Ne, ne, das ist ein eigener Datentyp.

Sven P. schrieb:
> Die Aufzählung selber kann char oder vorzeichenbehafteter oder -loser
> int sein, sollte aber Platz für alle Konstanten bieten.

Ich habe auch gerade nachgeschlagen: Es handelt sich um einen 
Integer-Typen. Aber die Größe hängt von der Implementierung ab.
#2266863
Lesenswert?

Linker schrieb:
> Peter Dannegger schrieb:
>> Bei einem Enum wird garnichts gespeichert.
>> Ein Enum ist wie ein Define nur ne Textersetzung.
>
> Ne, ne, das ist ein eigener Datentyp.

Nicht in C, aber in C++.

Wenn ich das hier:
1
#include <stdio.h>
2

3
typedef enum
4
{
5
  rot,
6
  gruen,
7
  blau
8
}  farbe_t;
9

10
void f( farbe_t farbe )
11
{
12
  printf( "%d\n", farbe );
13
}
14

15
int main( int nargs, char **args )
16
{
17
  f( 1 ); // Zeile 17
18

19
  return 0;
20
}
als C kompiliere (ANSI-C), läuft es klaglos durch.
Bei C++ dagegen gibt es Mecker:
1
t.cpp: In function ‘int main(int, char**)’:
2
t.cpp:17: error: invalid conversion from ‘int’ to ‘farbe_t’
3
t.cpp:17: error:   initializing argument 1 of ‘void f(farbe_t)’
Gast #2266881
Lesenswert?

Linker schrieb:
> Klaus Wachtler schrieb:
>> aber in C++
>
> Klaus Wachtler schrieb:
>> invalid conversion from ‘int’ to ‘farbe_t’
>
> Auch da nicht. Wie der Fehlertext zeigt, wird farbe_t als Datentyp
> angesehen. Bei reiner Textersetzung wäre es eine Zeichenkette.

Sorry Klaus, ich habe deine Antwort falsch verstanden.

In beiden Fällen handelt es sich um einen eigenen Datentyp. In C um 
einen Integer, der natürlich implizit gecastet wird.
#2266887
Lesenswert?

Klaus Wachtler schrieb:
>> Ne, ne, das ist ein eigener Datentyp.
>
> Nicht in C, aber in C++.

Doch, auch in C.

Klaus Wachtler schrieb:
> als C kompiliere (ANSI-C), läuft es klaglos durch.

Das ist doch kein Argument. Dass man jeden beliebigen Integer zuweisen 
kann und keine Limitierung auf die vorgebenden Konstanten besteht, ist 
halt eine Eigenschaft dieses Typs in C.

Konkret in C99:
1
6.2.5 Types
2
...
3
16 An enumeration comprises a set of named integer constant values.
4
   Each distinct enumeration constitutes a different enumerated type.
#2267017
Lesenswert?

Ja, aber der "eigene Datentyp" existiert nur auf dem Papier, weil er 
praktisch nicht von int unterschieden werden kann.

Egal, was du machst mit enums: sie unterscheiden sich nicht 
untereinander und nicht von int. Das gilt auch für C99.
Papier ist geduldig.

Eine Enumeration macht den Quelltext lesbarer, aber seitens des 
Compilers ist es insofern nur warme Luft, daß es keinerlei Typsicherheit 
gibt.
Genau das ist in C++ definitiv endlich verbessert.

Ganz gleich sind sie in der Tat nicht zugegebenermaßen: Zeiger auf int 
oder Zeiger auf enums werden dann doch wieder unterschieden, die falsche 
Verwendung führt wenigstens zu einer Warnung:
1
#include <stdio.h>
2

3
typedef enum
4
{
5
  rot,
6
  gruen,
7
  blau
8
}  farbe_t;
9

10
enum eSchuhgroesse
11
{
12
  fuenfundvierzig,
13
  sechsundvierzig,
14
  siebenundvierzig,
15
  achtundvierzig,
16
  neunundvierzig
17
};
18

19
void donau( enum eSchuhgroesse schuhgroesse )
20
{
21
  printf( "schuhgroesse ist %d\n", schuhgroesse );
22
}
23

24
void rhein( farbe_t farbe )
25
{
26
  printf( "farbe ist %d\n", farbe );
27
}
28

29
void elbe( int *p_int )
30
{
31
  printf( "die int ist %d\n", *p_int );
32
}
33

34
int main( int nargs, char **args )
35
{
36
  enum eSchuhgroesse   dasistkeinint = 12;
37
  farbe_t              dasauchnicht = siebenundvierzig;
38

39
  donau( 1 );                // seitens C richtig
40
  donau( fuenfundvierzig );  // seitens C richtig
41
  donau( blau );             // seitens C richtig
42

43
  rhein( 1 );                // seitens C richtig
44
  rhein( fuenfundvierzig );  // seitens C richtig
45
  rhein( blau );             // seitens C richtig
46

47
  elbe( &dasistkeinint );    // warning: passing argument 1 of ‘elbe’ from incompatible pointer type
48
  elbe( &dasauchnicht );     // warning: passing argument 1 of ‘elbe’ from incompatible pointer type
49

50
  return 0;
51
}
#2267018
Lesenswert?

Stefan Ernst schrieb:
> Das ist doch kein Argument. Dass man jeden beliebigen Integer zuweisen
> kann und keine Limitierung auf die vorgebenden Konstanten besteht, ist
> halt eine Eigenschaft dieses Typs in C.

Wenn es nur die Zuweisung wäre...

Sobald zwei Typen dagegen in allen Eigenschaften gleich sind, darf man 
schon anzweifeln, ob es wirklich zwei Typen sind.

Bei enum habe ich den Eindruck, daß man sie in C mal mit gutem Willen 
einführen wollte, und dann vergessen hat.

Du hast einerseits Recht, wenn du auf gedruckte Buchstaben verweist, das 
will ich dir nicht abstreiten.
Aber meine Seite ist: wie kann ich die unterschiedlichen Typen nutzen?
Was habe ich davon?
Und da bin ich noch nicht überzeugt, daß es einen Vorteil gibt, außer 
eben einem eleganteren Quelltext, solange der Programmierer sie nicht 
absichtlich oder versehentlich verwürfelt.
#2267020
Lesenswert?

Linker schrieb:
> Es ergibt die Anzahl in Byte, die der Compiler zum Speichern des
> definierten enum benötigt. Bei vielen wird es int sein.

Das beißt sich in vielen Fällen, da int nicht unbedingt nur 1 Byte groß 
ist.

Und in Byte ist leider falsch. Es gibt einige DSP, die 32 bit breit 
arbeiten. Und ein Speicherzugriff ist auch immer 32 bit breit. Dort gibt
sizeof(int) z.B. 1 zurück. sizeof(char) auch. Ein Zeichen belegt dort 
automatisch 32 bit.
Gast #2267029
Lesenswert?

Klaus Wachtler schrieb:
> Ja, aber der "eigene Datentyp" existiert nur auf dem Papier, weil er
> Eine Enumeration macht den Quelltext lesbarer, aber seitens des
> Compilers ist es insofern nur warme Luft, daß es keinerlei Typsicherheit
> gibt.

Das ist vermutlich der  Grund, warum enum in C recht selten überhaupt 
verwendet wird. Meistens werden stattdessen die Konstanten über #define 
angelegt und als Übergabetyp einfach int verwendet.

900ss D. schrieb:
> Linker schrieb:
>> Es ergibt die Anzahl in Byte, die der Compiler zum Speichern des
>> definierten enum benötigt. Bei vielen wird es int sein.
>
> Das beißt sich in vielen Fällen, da int nicht unbedingt nur 1 Byte groß
> ist.

Hä?

> Und in Byte ist leider falsch.

Nein.

> Es gibt einige DSP, die 32 bit breit arbeiten. Und ein Speicherzugriff ist auch
> immer 32 bit breit. Dort gibt sizeof(int) z.B. 1 zurück. sizeof(char) auch. Ein
> Zeichen belegt dort automatisch 32 bit.

Ja, also ein Byte.
Gast #2267058
Lesenswert?

900ss D. schrieb:
> Und in Byte ist leider falsch. Es gibt einige DSP, die 32 bit breit
> arbeiten. Und ein Speicherzugriff ist auch immer 32 bit breit. Dort gibt
> sizeof(int) z.B. 1 zurück. sizeof(char) auch. Ein Zeichen belegt dort
> automatisch 32 bit.

Bitte was? "Zeichen" hat hier gar nichts verloren.

Auf Architekturen wie du sie da beschreibst, hat ein Byte eben 32 Bit. 
Das ist dann aber noch immer ein Byte.
#2267075
Lesenswert?

Rolf Magnus schrieb:
> Ja, also ein Byte.

Martin schrieb:
> 900ss D. schrieb:
>> sizeof(int) z.B. 1 zurück. sizeof(char) auch. Ein Zeichen belegt dort
>> automatisch 32 bit.
>
> Bitte was? "Zeichen" hat hier gar nichts verloren.
>
> Auf Architekturen wie du sie da beschreibst, hat ein Byte eben 32 Bit.
> Das ist dann aber noch immer ein Byte.

OK, ich präzisiere, ein ASCII-Zeichen belegt dort 32 bit.

Und die Größe eines Byte belegt in meisten Fällen 8 Bit und genau dieser 
Meinung sind die meisten auch. Das dass nicht so ist, wissen viele 
nicht.
Die meisten Leute sind auch der Meinung, das sizeof(int) z.B. 1 
zurückgibt. Und das ist mitnichten so.

Das alles ist also architekturabhängig. Mehr wollte ich garnicht sagen.
Auch Wikipedia widerspricht sich in unterschiedlichen Artikeln.
So und nun kommt mal wieder runter. ;-)
Gast #2267097
Lesenswert?

900ss D. schrieb:
> OK, ich präzisiere, ein ASCII-Zeichen belegt dort 32 bit.

ASCII spielt hier überhaupt keine Rolle. enum ist ein Aufzählungstyp, 
der zu Integer zuweisungskompatibel ist! Nicht mehr und nicht weniger. 
So steht es geschreiben, so setzen es die Compilerbauer um.

900ss D. schrieb:
> Die meisten Leute sind auch der Meinung, das sizeof(int) z.B. 1
> zurückgibt.

Da unterstellst du den Leuten was. In diesem Thread habe ich das noch 
nicht gelesen.
Gast #2267108
Lesenswert?

enum schrieb:
> 900ss D. schrieb:
>> Die meisten Leute sind auch der Meinung, das sizeof(int) z.B. 1
>> zurückgibt.
>
> Da unterstellst du den Leuten was.
Sowas habe ich auch gedacht.

enum schrieb:
> In diesem Thread habe ich das noch nicht gelesen.
Aber ich:
900ss D. schrieb:
> Und in Byte ist leider falsch. Es gibt einige DSP, die 32 bit breit
> arbeiten. Und ein Speicherzugriff ist auch immer 32 bit breit. Dort gibt
> sizeof(int) z.B. 1 zurück. sizeof(char) auch. Ein Zeichen belegt dort
> automatisch 32 bit.

Für mich persönlich, nur aus dem Bauch, nicht sooo nachzuvollziehen, 
dass da eine Zeichenkette, die von irgendeiner Schnittstelle übernommen 
wird, dann auf die 4fache Länge gezerrt wird. (Und umgedreht mit viel 
Aufwand wieder komprimiert.)
Gast #2267127
Lesenswert?

900ss D. schrieb:
>> Auf Architekturen wie du sie da beschreibst, hat ein Byte eben 32 Bit.
>> Das ist dann aber noch immer ein Byte.
>
> OK, ich präzisiere, ein ASCII-Zeichen belegt dort 32 bit.

Ein ASCII-Zeichen belegt 7 Bit. Aber das hat mit C erstmal überhaupt 
nichts zu tun.

> Und die Größe eines Byte belegt in meisten Fällen 8 Bit und genau dieser
> Meinung sind die meisten auch. Das dass nicht so ist, wissen viele
> nicht.

Du anscheindend auch nicht, sonst hättest du das hier nicht geschrieben:

> Und in Byte ist leider falsch.


> Die meisten Leute sind auch der Meinung, das sizeof(int) z.B. 1
> zurückgibt.

Das würde mich wundern, denn es gibt nur wenige Plattformen, wo das 
gilt, und mit diesen kommen auch nur wenige Programmierer jemals in 
Kontakt.
Gast #2267129
Lesenswert?

Ralf schrieb:
>> Und in Byte ist leider falsch. Es gibt einige DSP, die 32 bit breit
>> arbeiten. Und ein Speicherzugriff ist auch immer 32 bit breit. Dort gibt
>> sizeof(int) z.B. 1 zurück. sizeof(char) auch. Ein Zeichen belegt dort
>> automatisch 32 bit.
>
> Für mich persönlich, nur aus dem Bauch, nicht sooo nachzuvollziehen,
> dass da eine Zeichenkette, die von irgendeiner Schnittstelle übernommen
> wird, dann auf die 4fache Länge gezerrt wird. (Und umgedreht mit viel
> Aufwand wieder komprimiert.)

Nun, irgendwann muß es ja gemacht werden. Entweder einmal beim Einlesen 
und einmal beim Rausschreiben, oder alternativ bei jedem einzelnen 
Speicherzugriff auf ein Zeichen.
Gast #2267144
Lesenswert?

Rolf Magnus schrieb:
> denn es gibt nur wenige Plattformen, wo das
> gilt, und mit diesen kommen auch nur wenige Programmierer jemals in
> Kontakt.
Also, zum Thema:

Arc Net schrieb:
> #define STATES { sdf, aew, dert, itgl, sfgds }
>
> enum anEnum STATES;
> int enumArray[] = STATES;
> const int numStates = sizeof(enumArray)/sizeof(int);
>
> (nicht schön, aber funktioniert für solche enums)
Trotz der 'Zaubereien', für mich ist das das Schönste. (Würde allerdings 
{} aus #define rausnehmen und in die anderen Deklarationen übernehmen. 
Find' ich übersichtlicher.)
#2267193
Lesenswert?

Ralf schrieb:
> Trotz der 'Zaubereien', für mich ist das das Schönste.

Für mich das Häßlichste.
Es wird nämlich unnötig SRAM verbraten, für nichts und wieder nichts.
Vielleicht ist der Compiler so schlau und stellt fest, daß dieses Array 
nirgends verwendet wird und optimiert es wieder raus.


Warum nicht einfach so:
Beitrag "Re: [c] sizeof(enum) bestimmen?"

Die Anzahl wird bestimmt dafür benötigt, daß man nicht eine ungültige 
Funktion aufruft. Und dann ist doch die Größe des Funktionsarrays 
bestimmend und nicht die Enum-Anzahl.


Peter
Gast #2267220
Lesenswert?

Peter Dannegger schrieb:
> Der Unterschied ist, daß das Funktionsarrays auch benutzt wird, ein
> Enum-Array in der Regel aber nicht.
Warum ich das Erste jetzt besser fand? Mit 'handelsüblichen' Datentypen 
ist das fix mal nachzuvollziehen (Stichwort: 'Bitte compilerbaren 
Code!'). Hast doch die Streitereien gelesen: sizeof() macht dieses! Nein 
sizeof() macht das...
Den 'int' durch den Funktionstyp zu ersetzen, hielt ich nicht für das 
Problem für den TO.
Gast #2267229
Lesenswert?

900ss D. schrieb:
> OK, ich präzisiere, ein ASCII-Zeichen belegt dort 32 bit.

Nein. Ein ASCII-Zeichen "belegt" sieben Bit.

> Und die Größe eines Byte belegt in meisten Fällen 8 Bit

Ja. Aber eben nicht immer. Und offenbar begreifst du das nicht, wenn du 
ständig von "Zeichen" statt von Bytes faselst.
#2267236
Lesenswert?

Klaus Wachtler schrieb:
> Arc Net schrieb:
>> reicht das
>
> Danke!
> Ich habe es eben mit dem gcc probiert, da zumindest geht es nur für
> genau 10 Werte. Darunter meckert der Compiler, darüber werden die
> Strings nicht mehr abgelegt.

Mehr als 10 ist klar (maximal halt das, was der Compiler/Präprozessor so 
festgelegt hat und das passend erweitert _11, _12 etc. wird).
Die folgende Variante funktioniert hier zumindest mit dem C32 (gcc)
1
 
2
#define STATES sdf, aew, dert, itgl, sfgds
3

4
#define EXPAND_VC(x) x
5
#define VA_NARGS_IMPL(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,N,...) N
6
#define VA_NARGS(...) EXPAND_VC(VA_NARGS_IMPL(__VA_ARGS__,10,9,8,7,6,5,4,3,2,1,0))
7
#define ARGS_TO_STR_IMPL(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,...) "" #_1, "" #_2, "" #_3, "" #_4, "" #_5, "" #_6 ,"" #_7, "" #_8, "" #_9, "" #_10
8
#define ARGS_TO_STR(...) EXPAND_VC(ARGS_TO_STR_IMPL(__VA_ARGS__, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
9
// statt 1, 2, ... kann man auch "illegal state" o.ä. einsetzen
10
enum anEnum { STATES };
11
char* enumStr[] = { ARGS_TO_STR(STATES) };
12
const int enumLength = VA_NARGS(STATES);


> Ich schaue es mir später noch in Ruhe an...
#2267238
Lesenswert?

enum schrieb:
> ASCII spielt hier überhaupt keine Rolle. enum ist ein Aufzählungstyp,

Jetzt reden wir aneinander vorbei, also stoppen wir hier.

Ralf schrieb:
> Für mich persönlich, nur aus dem Bauch, nicht sooo nachzuvollziehen,
> dass da eine Zeichenkette, die von irgendeiner Schnittstelle übernommen
> wird, dann auf die 4fache Länge gezerrt wird. (Und umgedreht mit viel
> Aufwand wieder komprimiert.)

Dann schau dir z.B. TMS320C31 oder ADSP21020 an.

Z.B.:

char s[]="ABC"; ergibt als dump;

0x41000000,
0x42000000,
0x43000000,
0x00000000

Rolf Magnus schrieb:
> Das würde mich wundern, denn es gibt nur wenige Plattformen, wo das
> gilt, und mit diesen kommen auch nur wenige Programmierer jemals in
> Kontakt.

Richtig :)

Wird langsam OT es hat nicht mehr wirklich was mit sizeof(enum) zu tun. 
Aber bei sizeof muß man eben die Architektur betrachten.
#2267240
Lesenswert?

Martin schrieb:
> 900ss D. schrieb:
>> OK, ich präzisiere, ein ASCII-Zeichen belegt dort 32 bit.
>
> Nein. Ein ASCII-Zeichen "belegt" sieben Bit.

Klugscheißer. ;-)

>> Und die Größe eines Byte belegt in meisten Fällen 8 Bit
>
> Ja. Aber eben nicht immer.

Immer hab ich auch nicht geschrieben, da steht meistens.

> Und offenbar begreifst du das nicht,
> wenn du ständig von "Zeichen" statt von Bytes faselst.

Lerne erstmal richtig zu lesen und zu verstehen bevor du mir faseln 
vorhälst.
Gast #2267365
Lesenswert?

meine güte herrschaften, da hab ich ja völlig unbewusst ne ziemliche, 
wenn auch interessante, diskussion vom zaun gebrochen..

auf dem sizeof() würd ich garnicht so sehr rumreiten, wollte hier bloß 
was haben was irgendwie gescheit in den titel gepasst hat, und in etwa 
aussagt, was ich brauche.

ich find den vorschlag von Peter Dannegger
Beitrag "Re: [c] sizeof(enum) bestimmen?"

absolut okay und praktisch, war mir nicht klar, das ich die [] auch 
einfach leer lassen kann, in dem fall.

herzlichen dank dafür!

mfg
#2267369
Lesenswert?

enum schrieb:
> oder den int-Typ, der benötigt auch keinen ...
>
> Wirkt etwas kleinkariert, oder?

Nö, überhaupt nicht. Man muß schon die Begriffe auseinanderhalten.

enum, define, typedef usw. belegen keinen Speicher, sie machen dem 
Compiler nur etwas bekannt.

Erst das Anlegen oder Initialisieren einer Variable belegt Speicher.


Peter
Persönliche Seite #2267393
Lesenswert?

900ss D. schrieb:
> Dann schau dir z.B. TMS320C31 oder ADSP21020 an.
>
> Z.B.:
>
> char s[]="ABC"; ergibt als dump;
>
> 0x41000000,
> 0x42000000,
> 0x43000000,
> 0x00000000

Ich glaube du verwechselst da was. Das, was man hier sieht nennt sich 
Padding und dient dazu den Code auf Plattformen, die nur ganzzahlige von 
(in diesem Falle) 4 Byte laden können zu verschnellern.
Persönliche Seite #2267412
Lesenswert?

Stefan Ernst schrieb:
> Simon K. schrieb:
>> Ich glaube du verwechselst da was. Das, was man hier sieht nennt sich
>> Padding und dient dazu den Code auf Plattformen, die nur ganzzahlige von
>> (in diesem Falle) 4 Byte laden können zu verschnellern.
>
> Es gibt kein Padding innerhalb von Arrays. Davor oder dahinter, ja,
> aber niemals zwischen den Elementen.

Ok!
Gast #2267417
Lesenswert?

Peter Dannegger schrieb:
> Für mich das Häßlichste.
> Es wird nämlich unnötig SRAM verbraten, für nichts und wieder nichts.
> Vielleicht ist der Compiler so schlau und stellt fest, daß dieses Array
> nirgends verwendet wird und optimiert es wieder raus.
>
>
> Warum nicht einfach so:
> Beitrag "Re: [c] sizeof(enum) bestimmen?"

Ralf schrieb:
> Peter Dannegger schrieb:
>> Der Unterschied ist, daß das Funktionsarrays auch benutzt wird, ein
>> Enum-Array in der Regel aber nicht.
> Warum ich das Erste jetzt besser fand? Mit 'handelsüblichen' Datentypen
> ist das fix mal nachzuvollziehen (Stichwort: 'Bitte compilerbaren
> Code!'). Hast doch die Streitereien gelesen: sizeof() macht dieses! Nein
> sizeof() macht das...
> Den 'int' durch den Funktionstyp zu ersetzen, hielt ich nicht für das
> Problem für den TO.

dunno.. schrieb:
> ich find den vorschlag von Peter Dannegger
> Beitrag "Re: [c] sizeof(enum) bestimmen?"
>
> absolut okay und praktisch, war mir nicht klar, das ich die [] auch
> einfach leer lassen kann, in dem fall.

@Peter
Habe mich geirrt...
#2267623
Lesenswert?

enum schrieb:
> Wenn wir schon beim Erbsenzählen sind:
> define wird vom preprocessor aufgelöst, das sieht der Compiler nicht.

Naja, wichtig ist, was hinten rauskommt (Helmut Kohl).
Welche Instanz nun die Ersetzung vornimmt, ist meistens schnurzpiepegal.

Für Anfänger ist es oft schwer zu verstehen, daß man Konstanten den 
Compiler selber ausrechnen lassen kann.
Es wird kein zusätzlicher Code erzeugt, aber man schreibt eine 
verständliche Formel hin, anstelle unverständlicher Hex-Zahlen.


Peter
Gast #2267630
Lesenswert?

Peter Dannegger schrieb:
> Für Anfänger ist es oft schwer zu verstehen, daß man Konstanten den
> Compiler selber ausrechnen lassen kann.
> Es wird kein zusätzlicher Code erzeugt, aber man schreibt eine
> verständliche Formel hin, anstelle unverständlicher Hex-Zahlen.

Da schweifen wir aber vom Thema ab: sizeof(enum)

Der OT will gar nicht den Speicherbereich der Variablen ermitteln, 
sondern er sucht die Anzahl an verschiedenen zuweisbaren Werte. Und das 
ist in C direkt nicht möglich.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren