Arrayinitialisierung nur per define möglich
-
#define für sowas verwenden und gut finden...
ich packs einfach nicht.
wenn ich von etwas nicht die adresse nehme, dann muss es auch keine adresse haben.
-
Tachyon schrieb:
Und wo kommt in Deinem kompilierten Binary dieser Wert her? Der Wert (die 0) steht im Binary. Wird das Programm geladen, steht es im Speicher und der Wert nimmt entsprechend den Platz weg.
Dust bezieht sich wohl eher auf eine Speicherstelle, die die Konstante geschrieben wird und dann vor dem Anlegen noch einmal aus dieser Speicherstelle gelesen werden muss.
Und wenn du einfach nur ein enum-Literal definierst und nicht benutzt, wirst du den Wert auch nicht im Binary finden.
dust schrieb:
Enums sind keine Variablen, sondern "echte" Konstanten. Befass dich vielleicht ein bisschen mit den Grundlagen.
Und warum sagst du das nicht gleich? Btw. gehört das nicht zu den Grundlagen, zumindest nicht in meinen Büchern. Da habe ich es gerade unter Erweiterte Typen gefunden, etliche Kapitel hinter Grundlagen. Und dort steht, dass enums sehr wohl Variablen sind ("C++ Objektorientiertes Programmieren von Anfang an").
Mit Grundlagen meine ich in dem Fall die Sprachfeatures (Schlüsselwörter etc.). Egal was irgend ein Buch über C++ dazu sagt.
Und bei enums muss man natürlich unterscheiden. Ich bezog mich auf enum Literale.
enum a { A = 1 // <- "enum Literal" }; enum a b; // <- "enum Variable"
Das größte Problem bei define ist übrigens die Namensraum Verunreinigung. Das merkt man schnell, wenn man schlecht geschriebene Libraries einbindet. Ein großer Hersteller hat in einem viel zu großen Header zB ein define auf so etwas ausgefallenes wie far oder near gelegt. Du kannst dir ja denken, was dann passiert.
Da enums ein Sprachfeature (und kein CPP Feature) sind, unterliegen sie auch Sichtbarkeitsbereichen.
#include <stdio.h> enum { N = 10 }; void foo() { printf("%d\n", N); } void bar() { enum { N = 100 }; printf("%d\n", N); } int main() { enum { N = 2 }; printf("%d\n", N); foo(); bar(); }
Ich hoffe, dass dir das Problem nun einigermaßen klar geworden ist. (wenn nicht, ersetz mal das enum durch ein #define). Das Problem tritt natürlich unabhängig davon auf, was man hinter das #define setzt.
dust schrieb:
ja, aber fuer test_enum geht unnötig Platz drauf (nicht, dass das schlimm wär, aber besser ist den Platz nicht zu brauchen)
Nein. Meinst du vielleicht
enum_test
? Das ist ja ein Beispiel, was ganz unabhängig von der Verwendung eines enum Literals für Arraylängen ist.
-
enum { N = 100 };
char arr [N];Hab's jetzt, denke ich. Ich fass mal zusammen:
Durch enum {N = 100} wird eine "echte" Konstante erzeugt, nämlich N. Dennoch wird, wie bei der Benutzung von #define, kein zusätzlicher Speicherplatz gebraucht, d.h. die 100 taucht nirgendwo als gespeicherter Wert auf, wie das bei einer Variable der Fall wäre. Zusätzlich merkt der Compiler sofort, wenn unsere Konstante kein Integer ist. Die perfekte Lösung!? Richtig so?
Werd das zukünftig so machen, anstatt mit #define.
-
rüdiger schrieb:
[letzter Post...]
Jo, danke. Du bringst das so recht gut auf den Punkt. So meinte ich das.
In C++ kann man enums allerdings in Namespaces packen, um die Sichtbarkeit einzuschränken. Mit defines geht das nicht.
-
Das kommt noch dazu. Schwere Geburt, aber das Kind ist da.
-
#define SIZE 5 int main() { //const unsigned int SIZE = 5; char string[SIZE] = "Test"; return 0; }
Um noch mal auf's Thema zu kommen:
Er definiert die Stringlänge gleich 2mal, einmal durch SIZE und dann durch
die Initialisierung des Strings. Es gibt nur recht wenige Spezialfälle wo so
etwas Sinn machen könnte.Nach enums hat kein Mensch gefragt.
Nastatt das ihr ihm Sinn oder Unsinn erklärt haut ihr euch gegenseitig wirres
Zeugs um die Ohren. Ich denke, der Erstposter hat da elementarere Probleme.
-
Das Problem des Erstposters ist längst gelöst, den schert das nicht, was wir hier noch ausgefochten/erarbeitet haben^^. Passte nur irgendwie.
-
in der tat, ich zitiere nochmal
moagnus schrieb:
Ich will nämlich die Konstante zur Bestimmung der Arraygröße benutzen und nicht die #define-Anweisung.
schon auf der ersten seite wurde festgestellt, dass dies mit C99 möglich ist. alles andere ist in diesem thread mehr oder wenig überflüssig gewesen
-
Hai Dust,
meinst Du der ist schon schreiend aus dem Fenster gesprungen ?
enum habe ich noch nie verwendet, ich wüßte auch nicht wofür ...
-
rüdiger schrieb:
#include <stdio.h> enum { N = 10 }; void foo() { printf("%d\n", N); } void bar() { enum { N = 100 }; printf("%d\n", N); } int main() { enum { N = 2 }; printf("%d\n", N); foo(); bar(); }
Ich hoffe, dass dir das Problem nun einigermaßen klar geworden ist. (wenn nicht, ersetz mal das enum durch ein #define).
#define N 10 void foo() { printf("%d\n", N); } void bar() { #undef N #define N 100 printf("%d\n", N); } int main() { #undef N #define N 2 printf("%d\n", N); foo(); bar(); }
ja, und?
wo ist da ein problem?
-
fricky schrieb:
rüdiger schrieb:
#include <stdio.h> enum { N = 10 }; void foo() { printf("%d\n", N); } void bar() { enum { N = 100 }; printf("%d\n", N); } int main() { enum { N = 2 }; printf("%d\n", N); foo(); bar(); }
Ich hoffe, dass dir das Problem nun einigermaßen klar geworden ist. (wenn nicht, ersetz mal das enum durch ein #define).
#define N 10 void foo() { printf("%d\n", N); } void bar() { #undef N #define N 100 printf("%d\n", N); } int main() { #undef N #define N 2 printf("%d\n", N); foo(); bar(); }
ja, und?
wo ist da ein problem?Danke, du hast gut gezeigt, warum man define nicht nehmen sollte. So spart man sich solche umständlichen define/undef Orgien.
Gut, dann ändern wir das Beispiel ein bisschen ab
include <stdio.h> enum { N = 10 }; void foo() { printf("%d\n", N); } void bar() { enum { N = 100 }; printf("%d\n", N); } void baz(); int main() { enum { N = 2 }; printf("%d\n", N); foo(); bar(); baz(); } void baz() { printf("%d\n", N); }
Klar kannst du hier wieder ein undef/define machen. Aber dann musst du die gleiche Konstante an mehreren Orten verwalten und wofür das ganze, wenn du ein einfaches enum nehmen kannst?
(btw. ich will nicht sagen, dass man define nie nie niemals benutzen darf. Ich benutze gerne define. Man muss sich nur bewußt sein, welche Nachteile das Sprachkonstrukt hat und hier hat es mehr Nachteile, als ein anderes Sprachkonstrukt (enum). Warum sich also damit rumquälen?)
-
rüdiger schrieb:
(btw. ich will nicht sagen, dass man define nie nie niemals benutzen darf. Ich benutze gerne define. Man muss sich nur bewußt sein, welche Nachteile das Sprachkonstrukt hat und hier hat es mehr Nachteile, als ein anderes Sprachkonstrukt (enum).
gegen enum hat ja auch keiner was (ich jedenfalls nicht).
nur gegen:const int my_const = ...; // <-- das ist doof
-
fricky schrieb:
rüdiger schrieb:
(btw. ich will nicht sagen, dass man define nie nie niemals benutzen darf. Ich benutze gerne define. Man muss sich nur bewußt sein, welche Nachteile das Sprachkonstrukt hat und hier hat es mehr Nachteile, als ein anderes Sprachkonstrukt (enum).
gegen enum hat ja auch keiner was (ich jedenfalls nicht).
nur gegen:const int my_const = ...; // <-- das ist doof
Warum denn? Oder trollst Du nur?
-
Nur fürs Protokoll
static int const a = 5; int main() { int const b = 10; return a + b; }
gcc-mp-4.3 -O3 -S foo.c
->.machine ppc .text .align 2 .globl _main _main: li r3,15 blr .subsections_via_symbols
Im übrigen sind defines auch beim debuggen nervig.
-
; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00.21022.08 TITLE C:\Users\Dennis\Desktop\test.c .686P .XMM include listing.inc .model flat INCLUDELIB LIBCMT INCLUDELIB OLDNAMES CONST SEGMENT _a DD 05H <------ zumindest speicher verbraucht das const int CONST ENDS PUBLIC _main ; Function compile flags: /Ogtpy _TEXT SEGMENT _main PROC ; File c:\users\dennis\desktop\test.c ; Line 5 mov eax, 15 ; 0000000fH ; Line 6 ret 0 _main ENDP _TEXT ENDS END
-
^^ haste den code auch mal ganz ohne die 'const' ausprobiert. ich wette da kommt das gleiche raus.
rüdiger schrieb:
Im übrigen sind defines auch beim debuggen nervig.
allerdings, da sind sie echt mies!
-
fricky schrieb:
^^ haste den code auch mal ganz ohne die 'const' ausprobiert. ich wette da kommt das gleiche raus.
rüdiger schrieb:
Im übrigen sind defines auch beim debuggen nervig.
allerdings, da sind sie echt mies!
Na dann erklär mal wie Sachen, die im zu kompilierenden Quelltext nicht auftauchen
können das Debuggen beinflussen. Das ist wirklich hanebüchen.
-
fricky schrieb:
^^ haste den code auch mal ganz ohne die 'const' ausprobiert. ich wette da kommt das gleiche raus.
Das ist anders, da ohne das const die sache veränderlich ist, und so theoretisch geändert werden kann(logisch, nicht?). Da die variable aber static ist und nirgends sonst genutzt wird, kann sie eigentlich entfernt werden, das wird sie aber wohl aus sicherheitsgründen nicht.
Und dass die variable im speicher sein sollte ist auch klar sonst wäre ja &constVar unmöglich.
-
wurst schrieb:
Und dass die variable im speicher sein sollte ist auch klar sonst wäre ja &constVar unmöglich.
Der Compiler kann ja einfach entscheiden, ob er die Konstante in den Speicher packt, je nachdem ob man ihre Adresse anspricht oder nicht.
-
Scheppertreiber schrieb:
fricky schrieb:
^^ haste den code auch mal ganz ohne die 'const' ausprobiert. ich wette da kommt das gleiche raus.
rüdiger schrieb:
Im übrigen sind defines auch beim debuggen nervig.
allerdings, da sind sie echt mies!
Na dann erklär mal wie Sachen, die im zu kompilierenden Quelltext nicht auftauchen
können das Debuggen beinflussen. Das ist wirklich hanebüchen.Denk doch bitte einmal nach, bevor du dich hier so aufführst. Es ist genau das Problem, dass es im Quelltext vorkommt, aber nicht beim "zu kompilierenden Quellcode". Für ein #define wird im Debugbuild kein Symbol angelegt, für ein enum oder ein const schon.
@fricky
Bei einem nicht const int kommt in diesem Fall natürlich das gleiche raus. Aber es ging ja um die Behauptung, dass bei einem const immer Speicher angelegt oder gar abgefragt werden muss.