Forum: Mikrocontroller und Digitale Elektronik [c] sizeof(enum) bestimmen?


von dunno.. (Gast)


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

von Haku (Gast)


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.

von Ralf (Gast)


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!?

von Ralf (Gast)


Lesenswert?

mal wieder zu spät...

von dunno.. (Gast)


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

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

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.

von dunno.. (Gast)


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.

von Ralf (Gast)


Lesenswert?

Also ich habe mal probiert:
1
enum E {eX, eY, eZ, eAnzahl};
2
uint8_t A[eAnzahl];
das nimmt der Compiler ohne zu murren.

von Ralf (Gast)


Lesenswert?

schon wieder zu spät.

von Stefan E. (sternst)


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?

von dunno.. (Gast)


Lesenswert?

hast recht, es geht natürlich auch ohne.. hatte bloß nen denkfehler, 
vorher...

von Arc N. (arc)


Lesenswert?

1
#define STATES { sdf, aew, dert, itgl, sfgds }
2
3
enum anEnum STATES;
4
int enumArray[] = STATES;
5
const int numStates = sizeof(enumArray)/sizeof(int);

(nicht schön, aber funktioniert für solche enums)

von Peterle A. (Firma: keine) (wanderameise)


Lesenswert?

sizeof liefert nicht die gesamtgröße wieder, sondern die größe eines 
elements, sprich eines INTs!

von Arc N. (arc)


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."

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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

sizeof wovon? Du meinst offenbar von einem enum-Element (ja, das ist 
dasselbe wie ein sizeof(int) ), Arc meint aber sizeof von einem Array.

Du hast da was velwechsert ;-)

von Peterle A. (Firma: keine) (wanderameise)


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


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..?)"

Klick auf "Antwort mit Zitat" vermeidet solche Missverständnisse.

von Peterle A. (Firma: keine) (wanderameise)


Lesenswert?

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

von Frank M. (ukw) (Moderator) Benutzerseite


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. ;-)

von Martin (Gast)


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 ;)

Wie kommst du auf das schmale Brett?

von Arc N. (arc)


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

von Klaus W. (mfgkw)


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!

von nocheinGast (Gast)


Lesenswert?

dunno.. schrieb:
> PWMStati

Für alle Nicht-Lateiner: Der Plural von Status ist Status mit langem "u" 
;)
Gut, das trägt nichts zum eigentlichen Problem bei, aber...

von Arc N. (arc)


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

von Ralf (Gast)


Lesenswert?

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

von dunno.. (Gast)


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

von Linker (Gast)


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.

von 900ss (900ss)


Lesenswert?

Linker schrieb:
> sizeof () gibt den Speicherbedarf zurück

Preisfrage: In welcher Einheit?

von Sven P. (Gast)


Lesenswert?

900ss D. schrieb:
> Linker schrieb:
>> sizeof () gibt den Speicherbedarf zurück
>
> Preisfrage: In welcher Einheit?
In Zeichen.

von Linker (Gast)


Lesenswert?

900ss D. schrieb:
>> sizeof () gibt den Speicherbedarf zurück
>
> Preisfrage: In welcher Einheit?

Sven P. schrieb:
> In Zeichen.

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

von Peter D. (peda)


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

von Rolf Magnus (Gast)


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.

von Linker (Gast)


Lesenswert?

Rolf Magnus schrieb:
> aber die Werte sind trotzdem immer vom Typ int. Und mit
> 0 wird dann begonnen, wenn man nicht explizit was anderes hinschreibt.

Und das ist C Standard und gilt bei jedem Compiler?

von Peter D. (peda)


Lesenswert?

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

Bei einem Enum wird garnichts gespeichert.
Ein Enum ist wie ein Define nur ne Textersetzung.


Peter

von Peterle A. (Firma: keine) (wanderameise)


Lesenswert?

Martin schrieb:
> 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 ;)
>
> Wie kommst du auf das schmale Brett?

ich habe es mir aus langeweile ausgedacht

von Sven P. (Gast)


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.

von Linker (Gast)


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.

von Linker (Gast)


Lesenswert?

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

Ach ja, konstanter Integer-Datentyp. Und die Zählung beginnt bei 0.

von Klaus W. (mfgkw)


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)’

von Linker (Gast)


Lesenswert?

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.

von Linker (Gast)


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.

von Stefan E. (sternst)


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.

von Klaus W. (mfgkw)


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
}

von Klaus W. (mfgkw)


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.

von 900ss (900ss)


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.

von Rolf Magnus (Gast)


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.

von Klaus W. (mfgkw)


Lesenswert?

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.

Ich schaue es mir später noch in Ruhe an...

von Martin (Gast)


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.

von 900ss (900ss)


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. ;-)

von enum (Gast)


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.

von Ralf (Gast)


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.)

von Rolf Magnus (Gast)


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.

von Rolf Magnus (Gast)


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.

von Ralf (Gast)


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.)

von Peter D. (peda)


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

von Ralf (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Warum nicht einfach so:
> Beitrag "Re: [c] sizeof(enum) bestimmen?"
Wo ist da der Unterschied? Dein Beispiel ist speziell für die benötigte 
Funktion zugeschnitten, das andere mit 'Beispieltyp int'. Hmm, klar, 
wenn man's so verwendet, dann ist das natürlich Quatsch.

von Peter D. (peda)


Lesenswert?

Ralf schrieb:
> Wo ist da der Unterschied?

Der Unterschied ist, daß das Funktionsarrays auch benutzt wird, ein 
Enum-Array in der Regel aber nicht.

Es mag ja unter C++ anders sein, aber in C ist ein Enum nur ein 
spezielles Define, welches keinen SRAM belegt.


Peter

von Ralf (Gast)


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.

von Ralf (Gast)


Lesenswert?

Ach so, dann vielleicht noch der Zusatz für normale Arrays:
'Bitte nicht nachmachen!' ;-)

von Martin (Gast)


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.

von Arc N. (arc)


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...

von 900ss (900ss)


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.

von 900ss (900ss)


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.

von enum (Gast)


Lesenswert?

Peter Dannegger schrieb:
> in C ist ein Enum nur ein
> spezielles Define, welches keinen SRAM belegt

Ufff, was ist jetzt los? Natürlich belegt ein enum RAM. Das ist eine 
ganz normale Variable. In C kannst man ihr aush einen int zuweisen.

von Stefan E. (sternst)


Lesenswert?

enum schrieb:
> Peter Dannegger schrieb:
>> in C ist ein Enum nur ein
>> spezielles Define, welches keinen SRAM belegt
>
> Ufff, was ist jetzt los? Natürlich belegt ein enum RAM. Das ist eine
> ganz normale Variable. In C kannst man ihr aush einen int zuweisen.

Er meinte damit nicht eine enum-Variable, sondern die enum-Konstanten.

von Klaus W. (mfgkw)


Lesenswert?

Oder den enum-Typ, auch der benötigt erstmal keinen Speicher.

von enum (Gast)


Lesenswert?

Klaus Wachtler schrieb:
> Oder den enum-Typ

oder den int-Typ, der benötigt auch keinen ...

Wirkt etwas kleinkariert, oder?

von dunno.. (Gast)


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

von 900ss (900ss)


Lesenswert?

dunno.. schrieb:
> diskussion vom zaun gebrochen..

Ich fragte mich vorhin auch schon, ob der TO überhaupt noch mitliest ;-)

von Peter D. (peda)


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

von Simon K. (simon) Benutzerseite


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.

von Stefan E. (sternst)


Lesenswert?

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.

von Simon K. (simon) Benutzerseite


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!

von Ralf (Gast)


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...

von enum (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Man muß schon die Begriffe auseinanderhalten.
>
> enum, define, typedef ... machen dem
> Compiler nur etwas bekannt.

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

von Klaus W. (mfgkw)


Lesenswert?

definiere: "Compiler"

von Peter D. (peda)


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

von enum (Gast)


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.

von Peter D. (peda)


Lesenswert?

enum schrieb:
> Der OT will gar nicht den Speicherbereich der Variablen ermitteln

Stimmt und die passende Lösung hat er bereits.


Peter

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.