Ich will hier Töne mit einem 8Bit Counter erzeugen, es soll aber geprüft
werden ob der Wert auch in ein 8Bit register passt. Falls nicht soll ein
Error ausgegeben werden.
Gibt es da überhaupt was?
Gruß Steven
Grundsätzlich ja, wenn Du Dich auf integer-Arithmetik beschränkst und
alle symbolischen Ausdrücke wiederum zum Zeitpunkt der Compilation
bekannt sind.
pow zur Basis 2 lässt sich durchaus durch eine Schiebeoperation
ersetzen.
Ich sehe da aber sowas wie "taste" dessen Definition bzw. Deklaration Du
nicht angegeben hast.
Danke für die Antwort!
Hmm schrieb:> pow zur Basis 2 lässt sich durchaus durch eine Schiebeoperation> ersetzen.
ich glaube das geht nicht, weil der Exponent rational ist?!
EDIT: achso ja, wenn ich Integer-Arithmetik benutzen würde. Muss mal
sehen ob ich da was umformen kann, hab in die Richtung noch nicht
nachgedacht...
Hmm schrieb:> Ich sehe da aber sowas wie "taste" dessen Definition bzw. Deklaration Du> nicht angegeben hast.
muss ich das? Kommt doch vom Makroaufruf...
Steven () schrieb:> ich glaube das geht nicht, weil der Exponent rational ist?!
Das geht nicht, weil der Präprozessor keine Funktion pow() kennt. Weil
er überhaupt keine Funktion kennt.
A. K. schrieb:> Das geht nicht, weil der Präprozessor keine Funktion pow() kennt. Weil> er überhaupt keine Funktion kennt.
Ich habs schon ausprobiert, er rechnet es vorher aus und setzt die Zahl
ein.
Wird scheinbar wegoptimiert.
Gruß Steven
Google spuckt einiges aus, z.B.
http://www.jaggersoft.com/pubs/CVu11_3.html , aber bei codepad kriege
ich den Kram so auf die Schnelle nicht zum Laufen. Aber es muss gehen...
Steven () schrieb:> Wird wegoptimiert
Im C Ausdruck ja, so der Compiler will. Das hat aber nichts mit dem
Präprozessor zu tun, denn der rechnet nirgends ausser in #if.
Du willst aber eine Fehlermeldung des Präprozessors, wenn ich dich
richtig verstanden habe. Das läuft auf irgendwas mit #if und #error raus
und da geht es zumindest offiziell nicht.
Steven () schrieb:> wie würde ich es denn machen, wenn ich keine Funktion drinstehen hätte?
Ähnlich dumm aus der Wäsche sehen, da der Präprozessor keine
Makro-Parameter kontrollieren kann. ;-)
Was du aber machen kannst: Den Ausdruck so schreiben, dass er im
Fehlerfall durch 0 dividiert. Dann warnt bereits der Compiler, so er das
zur Übersetzungszeit berechnet.
Das kann also sowas sein wie
#define f(x) (((x) <= 10) ? ... : 0/0)
Du musst dann nur im Kopf haben, was "division by zero" bei
t = f(11);
eigentlich bedeutet.
A. K. schrieb:> Ähnlich dumm aus der Wäsche sehen, da der Präprozessor keine> Makro-Parameter kontrollieren kann. ;-)
Ja ich guck schon zu lange dumm, heute.
Stimmt die Warnung bekomm ich auch, hab Sie nicht gesehen weil er Sie
mich nicht explizit gezeigt hat :)
Am besten wäre halt ein Error, ich werd mich noch umschauen.
Aber Danke! Habe jetzt mal ne Vorstellung.
Gruß Steven
Steven () schrieb:> Am besten wäre halt ein Error, ich werd mich noch umschauen.
Wenns weiter nichts ist: -Werror.
Warnings geflissentlich auszublenden ist nicht wirklich zu empfehlen.
>Hmm schrieb:>> Ich sehe da aber sowas wie "taste" dessen Definition bzw. Deklaration Du>> nicht angegeben hast.
Rufus Τ. Firefly schrieb:
>Das ist das Argument des Macros.
Steven () schrieb:
>muss ich das? Kommt doch vom Makroaufruf...
Ooops. Habe ich übersehen. Sorry.
A. K. (prx) schrieb:
>Du willst aber eine Fehlermeldung des Präprozessors, wenn ich dich>richtig verstanden habe. Das läuft auf irgendwas mit #if und #error raus>und da geht es zumindest offiziell nicht.
An sich ist #error schon Standard. K&R 2.Auflage, Seite 231
Oder habe ich Dich falsch verstanden?
Hmm schrieb:> An sich ist #error schon Standard. K&R 2.Auflage, Seite 231> Oder habe ich Dich falsch verstanden?
Zeig mal C Code, in dem der Präprozessor den Parameter eines Makros auf
einen Bereich von 1..10 kontrolliert und widrigenfalls #error ausspuckt.
Zeig ausserdem im Sinn der Sache funktionsfähigen C Code, in dem der
Präprozessor in der Bedingung eines #if Statements mit der C Funktion
pow() rumrechnet.
A.K. schrieb:
>Zeig mal ...
Warum sollte ich das tun? Ich bezog mich auf die zitierte Aussage von
Dir.
Die hat weder was mit dem Parameter eines Makros zu tun noch mit pow in
der Bedingung eines Makros. Sondern nur damit ob #error Standard ist.
Ich hatte Steven so verstanden, dass er etwas machen will, was auf die
beiden gestellten Fragen hinaus läuft. Und bestritten, dass das mit dem
Präprozessor geht. Nicht aber bestritten, dass es #error gibt.
Also eine Frage hab ich noch.
A. K. schrieb:> ... funktionsfähigen C Code, in dem der> Präprozessor in der Bedingung eines #if Statements mit der C Funktion> pow() rumrechnet.
geht es denn ohne pow?
Hallo Mhm, das hab ich auch nicht vergessen.
Aber kann man bei
#define einMakro(einWert) einWert*2
prüfen, ob der Wert auch in einem gewissen Bereich liegt?
Allerdings kann man den Compiler nutzen, um es zur Compilezeit zu
prüfen, was letztendlich auch ausreichen sollte. Der Klassiker dafür
ist, aus dem Wert eine Array-Größe zu berechnen, die negativ wird, wenn
der Wert nicht paßt. Der Compiler bricht dann mit Fehler ab, da negative
Array-Größen nicht erlaubt sind.
Hier mal ein aus dem Internet geklautes Beispiel:
>Mit dem C-Präprozessor selbst kann man das nicht.
Falsch !
Mit dem Preprozessor geht einiges. Es gibt Leute, die schreiben
komplette Programme mit Preprozessor-Makros.
Prüfen von Macro-Parametern auf Glültikgeit ist eine Kleinigkeit.
Allerdings ist der Makro-Verhau nicht gerade übersichtlich und einfach
zu verstehen. Eine kleine Demonstration der Möglichkeiten findet sich
z.B. hier:
http://cakoose.com/wiki/c_preprocessor_abuse oder hier:
http://www.boost.org/doc/libs/1_53_0/libs/preprocessor/doc/index.html
Wenn es nicht unbedingt im Makro selbst getestet werden muss:
<util/setbaud.h> in der avr-libc implementiert eine vergleichbare
Parameterprüfung. Das funktioniert, indem man einige Makros gemäß
Anleitung in der Doku zuerst setzen muss, und erst danach
<util/setbaud.h> inkludiert. Dieses modelt dann allerlei
Augabe-Makros daraus um (und kann auch #warnings werfen), die man
hernach im Code benutzen kann.
Braucht man es nochmal mit anderen Eingabeparametern, kann man diese
per #undef und #define neu setzen und den Header nochmals inkludieren.
Damit ist er einer der wenigen Header (wie auch <assert.h>), die sich
ausdrücklich nicht gegen mehrfaches inkludieren schützen.
Soviel nur mal als Anregung, vielleicht wäre das ja für den TE eine
sinnvolle Alternative.
Preprozessor schrieb:
>>Mit dem C-Präprozessor selbst kann man das nicht.> Falsch !>> Mit dem Preprozessor geht einiges. Es gibt Leute, die schreiben> komplette Programme mit Preprozessor-Makros.
Soweit mir erinnerlich wollte er nicht wissen, was man sonst alles mit
dem Präprozessor machen kann, sondern wie man ganz konkret sein
beschriebenes Problem damit lösen kann. Und da stehe ich bis zum Beweis
des Gegenteil dazu, dass man unter ausschliesslicher Nutzung des
Präprozessors die Werte von Makroparametern nicht überprüfen kann.
Wie schon skizziert wurde geht es jedoch in Zusammenspiel mit dem
Compiler, also beispielsweise dem Array mit negativer Anzahl Elemente.
Jörg Wunsch schrieb:> Wenn es nicht unbedingt im Makro selbst getestet werden muss:
Eben. Werte von #defines zu testen ist kein Problem. Dazu sind #if
Statements in der Lage. Aber Makroparameter - no way.
In etwa so:
Der Ausdruck 2*(440*pow(2,((taste-49)/12))) muß für alle möglichen Werte
von 'taste' von Hand berechnet vorberechnet werden.
Das Ergebnis der gesamten Berechnung schreibt man wieder in ein #define
dessen Wert man dann mit #if überprüfen kann.
Innerhalb der #if-Anweisung kann der Preprozessor mit den
Grundrechenarten (+,-,/,*) umgehen. Float und math. Funktionen gehen
nicht direkt aber wie beschrieben über eine Tabelle.
Preprozessor schrieb:> Das Ergebnis der gesamten Berechnung schreibt man wieder in ein #define> dessen Wert man dann mit #if überprüfen kann.
Das entspricht ungefähr dem, was ich für <util/setbaud.h> meine.
Ist aber weit davon entfernt, die Überprüfung eines Makro-Parameters
zu sein. Außerdem musst du natürlich alle möglichen Werte für
taste_* auskodieren.
Hallo,
für das Beispiel hat mir eine Exceltabelle die nötigen Werte berechnet.
Ich fände es gut, wenn der standard Präprozessor etwas mächtiger wäre.
Gruß
Steven
Steven () schrieb:> Ich fände es gut, wenn der standard Präprozessor etwas mächtiger wäre.
Da bist du nicht der Einzige. Aber man kann ja dank makefiles immer noch
irgendein Skript vor den Compiler schalten. Oder m4(?).
Simon G. schrieb:> Ich nutze folgendes um die größe eines Arrays (empfaengermaske) zu> überprüfen
Gut und schön, aber was hat das mit dem Präprozessor (und damit dem
Thema des Threads) zu tun?
Schreib doch einfach ein kleines Programm, das übersetzt und dann
ausgefüht wird.
Im Fehlerfalle bricht make den Build-Prozess ab. Damit kommt der Fehler
zwar nicht vom Präprozessor, aber das spielt im Endeffekt bestimmt nur
eine untergeordnete Rolle. Weiterer Vorteil ist, daß die avr-Quelle
einfacher wird.