C_programmer wrote:
> MAX_ANZ ist 2> TempMwInit ist eine u16 constante
Leider ist das in C keine Konstante wie in C++, sondern eine Variable
mit konstantem Wert. Und das macht den Unterschied.
>Leider ist das in C keine Konstante wie in C++, sondern eine Variable>mit konstantem Wert. Und das macht den Unterschied.
Da komme ich nicht ganz mit!
1
constu16TempMwInit=120;
ist doch eine konstante?
Warum kann ich diese dann nicht als Initialisierer benutzen?
Oder kommt mir da der Prä-Prozessor dazwischen? Der den "Variablennamen"
nicht auflöst ?!
Danke!
C_programmer wrote:
>>Leider ist das in C keine Konstante wie in C++, sondern eine Variable>>mit konstantem Wert. Und das macht den Unterschied.>> Da komme ich nicht ganz mit!>
1
>constu16TempMwInit=120;
2
>
>> ist doch eine konstante?>> Warum kann ich diese dann nicht als Initialisierer benutzen?> Oder kommt mir da der Prä-Prozessor dazwischen? Der den "Variablennamen"> nicht auflöst ?!
Nö, der Präprozessor löst keine Variablennamen auf.
Du kannst
1) TempMwInit als Makro definieren
2) Per -DTempMwInit auf der Kommandozeile definieren
3) TempMwInit als lokale static-Variable anlegen
4) Einen Konstruktor schreiben (GNU-Erweiterung) und dort von Hand
initialisieren, bevor main aufgerufen wird.
Johann
> ist doch eine konstante?
Es ist eine Read-Only-Variable (also das, was Karl Heinz schon vermutet
hat). Solche Variablen (die streng genommen gar nicht variabel sind)
dürfen nicht überschrieben werden, haben aber ansonsten alle
Eigenschaften von gewöhnlichen Variablen. Insbesondere könnte so eine
Variable auch in einer anderen Übersetzungseinheit definiert und in der
aktuellen mit "extern" deklariert werden. Dann kann der Compiler ihren
(konstanten) Wert nicht kennen.
Um solche und ähnliche Probleme zu umgehen, dürfen Variablen (auch
Read-Only-Variablen) generell nicht als Initialisierer von statischen
Variablen verwendet werden. Dort sind nur "direkte" (also lokal
auflösbare) Konstanten erlaubt. Dazu zählen numerische Literale (z.B. 3,
-2.5e-3 usw.), String-Literale, konstante Ausdrücke (z.B. 3+4,
"Text"[3], sizeof-Ausdrücke usw.).
Solche Ausdrücke dürfen auch in Makros verpackt werden. Das ist auch der
gängige Weg, Konstanten mit Namen zu definieren (s. Vorschlag 1 von
Johann).
Johann L. schrieb:
> 3) TempMwInit als lokale static-Variable anlegen
Sicher? Da hast du doch wieder das Problem, dass eine Variable als
Initialisierer verwendet wird.
yalu wrote:
> Johann L. schrieb:>>> 3) TempMwInit als lokale static-Variable anlegen>> Sicher? Da hast du doch wieder das Problem, dass eine Variable als> Initialisierer verwendet wird.
Ja, jetzt bin ich sicher. Es geht nämlich auch nicht als static const
;-)
Sven P. wrote:
> Wenn es numerische Konstanten sind, empfiehlt die Bibel (K&R), statt> #define lieber enum zu benutzen:> [...]> Hat dann den Vorteil, dass der Compiler die auch als benannte Konstanten> (und nicht als Literale) sieht, sagt K&R.
Kommt auf die Anwendung an. An Makros ist nett, daß man sie überprüfen
kann, etwa in
1
#if F_CPU % IRQS_PER_SECOND != 0
2
#warning Timer arbeitet ungenau!
3
#endif
4
5
#if F_CPU / IRQS_PER_SECOND > 0xff
6
#error Timer ist nur ein 8-Bit Timer
7
#endif
Mit enums geht das nicht, weil es leider immer noch kein
1
__builtin_error("Hier ist ein Fehler");
gibt, das man zusammen mit builtin_choose_expr verwenden könnte (und
wenn, ist's "nur" GNU-C).
Die Typisierung bei Enums kann hilfreich sein (Typprüfungen, Warnungen
bei switch), oder aber nerven, weil's schlechten Code gibt, z.B. in
Zusammenhang mit -fshort-enums.
Ich verwende beides, Enums und Makros. Immer das, was am besten passt
:-)
Johann
Johann L. wrote:
> Kommt auf die Anwendung an. An Makros ist nett, daß man sie überprüfen> kann, etwa in
Das is auch wieder wahr.
> Mit enums geht das nicht, weil es leider immer noch kein[...]
Ist aber nicht mit bedingter Kompilierung zu verwechseln -- auch da
tendiert der K&R zu ganz gewöhnlichen if() {} und verweist auf den
Optimierer :-)
> Die Typisierung bei Enums kann hilfreich sein
...wenn sie denn benutzt würde grins abgesehen von switch() mein ich
(in C, in C++ sieht das schon anders aus).
ok, das habe ich jetzt verstanden!
Danke an Alle!
Leider ist es nicht möglich, dass ich den Wert per Define anlege, da der
Initialisierungsparameter aus einem C-File kommt, welches separat
ausgetauscht werden kann (Flash Parameter).
In der Header-Datei ist diese Variable als extern deklariert und in dem
entsprechenden C-File definiert.
Also blieb mir nichts anderes übrig, als den 2D Puffer modul-global zu
machen und in der Init Funktion des Moduls den Puffer mit dem
Initialisierungswert zu initialisieren.
Aber danke! Jetzt weiß ich zumindest warum Ansatz 1 falsch war! :-)
Wieder was gelernt!
Ciao!
Ah, noch ein Hinweis, warum ich so ein großes "Drum-Herum" um diese
Initialisierung mache.
Also bei dem Puffer handelt es sich um einen Puffer für einen einfachen
digitalen Filter. Aber der Filter muss halt mit etwas vernünftigem
Initialisiert sein, ansonsten ist die "Einschwingzeit" zu groß.
Und mit dem Initialisierungswert aus dem separaten C-File wird eben
dieser Filter sozusagen konfiguriert.
Ciao
>Dann initialisiere den Puffer doch einfach mittels Zuweisungen, dann>hast du die ganzen Probleme nicht.
Das habe ich ja damit gemeint, also mit der Initialisierung in der Init
Funktion des Moduls. Dort habe ich es dann über einmalige Zuweisungen
gelöst.