Hi,
ich schreibe für einen Tricore TC1797 in C ein Programm zum
Sensorauswerten und bin über die Präprozessoranweisungen #if und #else
gestoßen.
Damit kann man ja scheinbar den Code wählen, der kompiliert werden soll.
Ich habe eine C-Datei über die ich bestimmte Sachen festlegen will.
Ein Beispiel: Soll die Endwertberechnung über Filter stattfinden oder
nicht? Dazu gibt es einen Parameter.
Im Interrupt soll dann nur der entsprechende Quellcode übersetzt werden.
Beispiel:
#if(Parameter1>0)
function1();
#else
function2();
#endif
Über die C-Datei will ich eine Vielzahl von solchen Optionen einbauen,
mit denen man das Programm variabel machen kann. Damit nicht in jedem
Interrupt viele if-Abfragen stattfinden, soll der Compiler nur die
benötigten Codezeilen übersetzen.
Oder ist das #if nicht für eine solche Verwendung gedacht?
Ist es nur in Kombination mit #define konzipiert?
danke, Michael H.
So richtig schlau werd ich aber nicht daraus.
Sagt der Text, dass es teilweise mit manchen Compilern nicht richtig
geht?
Mein Code sieht z.B. folgendermaßen aus:
#if ((filterAddLength01!=0x00)||(filterMavLength01!=0x00))
put(buffer01,bufferSize01,&posPut01,FADC_uwGetFinalFilterResult(0),&n01)
;
#else
put(buffer01,bufferSize01,&posPut01,FADC_uwGetChannelConversionResult(0)
,&n01);
#endif
Irgendwie scheint er dabei meistens ins else-Statement zu gehen.
Wenn ich die beiden Parameter filterAddLength01 und filterMavLength01
auf einen anderen Wert als 0x00 setze, scheint er manchmal dieses und
manchmal jenes zu machen.
Kann leider keinen Zusammenhang ausmachen!
Wolfgang schrieb:> Minty Mint schrieb:>> #if ((filterAddLength01!=0x00)||(filterMavLength01!=0x00))>> Ob dein Präprozessor das alles versteht?
Warum nicht? Wenn filterAddLength01 eine Präprozessorkonstante ist passt
das. Wenn es aber eine Variable ist hat der TO was falsch verstanden...
... ich schreibe für einen Tricore TC1797 in C ein Programm ... Im
Interrupt soll dann nur der entsprechende Quellcode übersetzt werden
...
Also irgendwas passt hier nicht zusammen. Oder haue ich da ein paar
Begriffe durcheinander?
Minty Mint schrieb:> Mein Code sieht z.B. folgendermaßen aus:>> #if ((filterAddLength01!=0x00)||(filterMavLength01!=0x00))> put(buffer01,bufferSize01,&posPut01,FADC_uwGetFinalFilterResult(0),&n01) ;> #else> put(buffer01,bufferSize01,&posPut01,FADC_uwGetChannelConversionResult(0) ,&n01);> #endif
Woher kommen filterAddLength01 und filterMavLength01? Variablen oder
#define?
OK, danke für die Tipps.
Jetzt funktioniert es soweit.
Hatte filterAddLength01 als globale Variable definiert.
Hab das nun zu einem #define gemacht.
Unter dem geposteten Link hab ich nicht alles gelesen.
Wär auch recht viel.
Demnach muss man das immer über #define machen, sonst gehts nicht, oder?
Was für einen Datentyp liefern solche Defines eigentlich?
Soweit ich weiß geht das mit int und long.
Peter II schrieb:> überhaupt keine, es sind ja auch keine Variablen. Ist es nur Text.
blödsinn.
das sind integer. was ein integer ist, findest du in der dokumentation
deines compilers.
üblicherweise: 16 bit signed.
Minty Mint schrieb:> mit denen man das Programm variabel machen kann. Damit nicht in jedem> Interrupt viele if-Abfragen stattfinden, soll der Compiler nur die> benötigten Codezeilen übersetzen.
Wenn wie hier die abgefragten Dinge konstant sind, dann wird der
Compiler die Abfragen bereits bei optimierten Übersetzen auflösen und
den unmöglichen Code eliminieren.
Exzessive Verwendung von diesen Präprozessor-Direktiven ist nicht
sonderlich übersichtlich. Wenn solcherart ausgeblendeter Code vom
Compiler nicht akzeptiert wird, dann sind sie nötig. Andernfalls sind
normale Abfragen weit lesbarer.
der c präprozessor kennt üblicherweise kein float, string und sonstiges.
er kann integer verschiedener länge verarbeiten. der rest ist
textersetzung.
lest die doku.
Michael H. schrieb:> willst du mir jetz sagen, 5 und 5 seien text?
Der PP hält sie tatsächlich erstmal als Text.
Nur im Vergleich mit < wird daraus eine Zahl.
Das sieht man z.B. wenn man eine vermeintliche Zahl mit einem
merkwürdigen Format definiert (mit führendem + bspw.) und dann wieder
irgendwie ausgibt, z.B. über # als String: dann taucht die Zahl in ihrem
ursprünglichen Format auf, und nicht aus einer Zahl in eine
Standarddarstellung konvertiert.
Mini Float schrieb:> Das sind Textschnipsel
DEIN beispiel schon.
der TO will aber die conditionals des präprozessors selbst benutzen. und
der kann nun mal integer.
Klaus Wachtler schrieb:> Der PP hält sie tatsächlich erstmal als Text.> Nur im Vergleich mit < wird daraus eine Zahl.
nichts andres sag ich doch...
wenn hier jeder meint, er müsse dagegenreden, damit die luft mal
schwingt, wirds mir zu blöd.
lest die doku, sie gibt mir recht.
Michael H. schrieb:> lest die doku, sie gibt mir recht.
[...]
Formally, preprocessing numbers begin with an optional period, a
required decimal digit, and then continue with any sequence of letters,
digits, underscores, periods, and exponents.
[...]
The purpose of this unusual definition is to isolate the preprocessor
from the full complexity of numeric constants.
[...]
Erst durch einen Vergleich mit #if oder #ifdef wird veranlasst, dass der
Textschnipsel als -wie immer auch geartete- Zahl interpretiert und
verwendet wird.
Ich klink mich aus.
Mini Float schrieb:> Erst durch einen Vergleich mit #if oder #ifdef wird veranlasst, dass der> Textschnipsel als -wie immer auch geartete- Zahl interpretiert und> verwendet wird.
Und dort gilt als Daumenregel "Schrott rein Schrott raus". #if
Statements akzeptieren als Bedingung ziemlich viel Blödsinn ohne sich
drüber zu beschweren. Das sorgt mitunter für Irritationen, wenn etwas,
was im "if" Statement als Syntax Error angezeigt würde, vom #if
kommentarlos gefressen wird. Nicht immer zur Freude des Programmierers.
Sebastian M. schrieb:> so?
Im Prinzip ja, aber dies führt zu recht hässlichem Code, wenn alle paar
Zeilen so eine #if/#endif Klammer steht.
Besser beispielsweise:
1
#if debug
2
# define TRACE(s) uart_puts(s)
3
#else
4
# define TRACE(s)
5
#endif
6
7
...
8
TRACE("Debugmodus AN");
9
...
10
TRACE("Panic!");
Weil man so beliebig viel Trace-Kram einstreuen kann, ohne dass es
unübersichtich wird.
Freunde von printf können das auch ohne varargs-Makros haben:
>Freunde von printf können das auch ohne varargs-Makros haben:>#if debug># define TRACE(s) printf s>#else># define TRACE(s)>#endif
Geht auch so
#if debug
# define TRACE printf
#else
# define TRACE(...)
#endif
Danke für die Hilfe!
Das ist echt ein Spitzenboard hier!
Man kriegt einfach immer Antworten und eine brauchbare ist stets dabei.
Soll ich jetzt eigentlich diese #if und #else verwenden oder ist das
sowieso hinfällig, wenn man darüber nur #defines abfragt?
prx schrieb:
"Wenn wie hier die abgefragten Dinge konstant sind, dann wird der
Compiler die Abfragen bereits bei optimierten Übersetzen auflösen und
den unmöglichen Code eliminieren.
Exzessive Verwendung von diesen Präprozessor-Direktiven ist nicht
sonderlich übersichtlich. Wenn solcherart ausgeblendeter Code vom
Compiler nicht akzeptiert wird, dann sind sie nötig. Andernfalls sind
normale Abfragen weit lesbarer."
Soll ich nun if oder #if verwenden?
Minty Mint schrieb:> Soll ich jetzt eigentlich diese #if und #else verwenden oder ist das> sowieso hinfällig, wenn man darüber nur #defines abfragt?
Meine Meinung: Schreibe deine Programme möglichst ohne #if und ohne
#ifdef
Das ist Präprozessorakrobatik und dient eigentlich nur dazu, aus einigen
ähnlichen Quellen eine einzige Quelle zu machen. Am Ende wird das alles
nur unübersichtlich und schwerfällig. Wenn du für 2 ähnliche Probleme 2
unterschiedliche Programme brauchst, dann mach für jedes Problem eines.
Andererseits kann es ja vorkommen, daß dein Programm verschiedene Fälle
beachten muß (zur Laufzeit, wohlgemerkt), dann ist #if regelrecht
falsch.
Ich hatte schon Quellen, wo sich #ifdef .... #endif Konstrukte über
mehrere verschiedene Quellen hinzogen, so daß man am Ende gar nicht mehr
nachvollziehen konnte, was denn tatsächlich im erzeugten Code landete.
Das war ein Obermist.
Ach ja, nochwas: Spaghetticode (Relikt von BASIC) und die Verwendung von
goto_ in C sind was _verschiedenes. Also schreibe dort, wo es sachlich
hinpaßt besser goto und vermeide sowas wie while(1){....};
W.S.
hm, mir wurde 2 mal beigebracht, dass man keinesfalls goto verwenden
soll.
deswegen stelle ich auch deine andere Antwort in Frage, W.S..
Letztendlich brauche ich für verschiedene Anwendungsfälle verschiedenen
Code.
Die Frage ist dann: Wird bei normalem "if" auch sicher nur der nötige
Code übersetzt oder nicht?
Oder soll ich auf Nummer sicher gehen mit #if?
Was meint ihr?
Wozu gibt es dann überhaupt die #if-Funktion, wenn der Compiler sowieso
den überflüssigen Code wegkürzt?
W.S. schrieb:> Ach ja, nochwas: Spaghetticode (Relikt von BASIC) und die Verwendung von> goto_ in C sind was _verschiedenes. Also schreibe dort, wo es sachlich> hinpaßt besser goto und vermeide sowas wie while(1){....};
Das ist mal ein recht seltsamer Tipp. Falls du das meinst
Minty Mint schrieb:> Die Frage ist dann: Wird bei normalem "if" auch sicher nur der nötige> Code übersetzt oder nicht?
Ja, wenn der Compiler etwas taugt.
> Oder soll ich auf Nummer sicher gehen mit #if?> Wozu gibt es dann überhaupt die #if-Funktion, wenn der Compiler sowieso> den überflüssigen Code wegkürzt?
Weil es Fälle gibt, in denen man mit if() nicht weiter kommt.
Beispielsweise bei
Peter II schrieb:> nein, er meint vermutlich soetwas:
D´accord. Bei solchen Konstruktionen ist goto sinnvoll, jedenfalls wenn
sie grösser sind als dieses Beispiel.
Minty Mint schrieb:> hm, mir wurde 2 mal beigebracht, dass man keinesfalls goto verwenden> soll.> deswegen stelle ich auch deine andere Antwort in Frage, W.S..
Tja, sowas stimmt mich ein bissel traurig. Dir wurde es also SO
beigebracht... hmm in meinem Inneren grummelt die Frage, ob die jungen
Leute heutzutage etwas gelehrt bekommen, den Sinn verstanden und es
somit gelernt haben oder ob sie lediglich dressiert bzw. abgerichtet
werden.
Im Klartext: das Wort "goto" gehört zum Grundwortschatz von C und vieler
anderer Programmiersprachen. Du darfst deinen Lehrern einen schönen Gruß
von mir ausrichten und daß sie sich nach 30 jährigem Tiefschlaf mal
aufraffen mögen, ihre Köpfe endlich auszumisten. Damals war BASIC die
schlichtweg überragende Programmiersprache auf allem, was man heute "PC"
nennen würde. Selbst der Ur-IBM-PC hatte zuallererst einen residenten
Basicinterpreter drin. Da aber das damalige Basic im Wesentlichen auf
Zeilennummern beruhte, war ein buntes Durcheinander von GOTO's
schlichtweg nötig.
Aus dieser Zeit stammt der Rat, "goto" möglichst zu vermeiden und sich
der anderen Konstrukte zu bedienen, die die damals aufkommenden neuen
Programmiersprachen Pascal und C boten: case bzw. switch, do while,
repeat until und so.
Pauschal das goto zu verteufeln und dies zu verabsolutieren ist reiner
Unsinn. Aber offenbar wird den jungen Leuten heutzutage eben genau
dieser Unsinn eingebleut und diese verinnerlichen das ohne es kritisch
zu hinterfragen. Kurzum, sowas stimmt mich traurig.
W.S.
Minty Mint schrieb:> Letztendlich brauche ich für verschiedene Anwendungsfälle verschiedenen> Code.
und dann stellt sich halt die frage: kannst du die fälle erst zur
laufzeit oder schon zur compilezeit unterscheiden?
> Die Frage ist dann: Wird bei normalem "if" auch sicher nur der nötige> Code übersetzt oder nicht?
grundsätzlich: ja, wird mitübersetzt.
> Oder soll ich auf Nummer sicher gehen mit #if?
es wäre hilfreich, wenn du diese recht einfache entscheidung selbst
fällen würdest, nachdem du denn verstanden hast, was #if und if denn nun
sind.
#if ist eine reine präprozessoranweisung. klammerst du befehle in ein
#if-conditional, das nicht erfüllt ist, behandelt es der compiler, als
wäre es nicht da.
W.S. schrieb:> hmm in meinem Inneren grummelt die Frage, ob die jungen> Leute heutzutage etwas gelehrt bekommen, den Sinn verstanden und es> somit gelernt haben oder ob sie lediglich dressiert bzw. abgerichtet> werden.
Das wird bei dir wie bei mir nicht anders gewesen sein: man bekommt
nicht alles breit erklärt oder häppchenweise vorgekaut. Wer Interesse an
seinem Werdegang hat, informiert sich eigenständig und versucht nicht
nur auswendig zu lernen, sondern eben zu verstehen. Wer diese
Eigenverantwortung nicht annimmt, ist selbst schuld.
Mein Arbeitsplatz fühlt sich nach so einem Thread immer ein bisschen
sicherer an :)
Michael H. schrieb:> Minty Mint schrieb:>> Letztendlich brauche ich für verschiedene Anwendungsfälle verschiedenen>> Code.> und dann stellt sich halt die frage: kannst du die fälle erst zur> laufzeit oder schon zur compilezeit unterscheiden?
die fälle sind schon zur compilezeit klar.
>> Die Frage ist dann: Wird bei normalem "if" auch sicher nur der nötige>> Code übersetzt oder nicht?> grundsätzlich: ja, wird mitübersetzt.
das ist eine etwas widersprüchliche antwort. das "ja" sagt, es wird nur
der nötige Code übersetzt, das "wird mitübersetzt" sagt, dass der
unnötige Rest auch übersetzt wird.
wie nun?
W.S. schrieb:> Damals war BASIC die schlichtweg überragende Programmiersprache
Die "goto" Debatte geht wesentlich auf ältere Sprachen wie FORTRAN und
COBOL zurück.
Minty Mint schrieb:> das ist eine etwas widersprüchliche antwort.
Stimmt, entschuldigung!
Was du hinschreibst, wird übersetzt, außer der Compiler kann sicher
feststellen, dass das Conditional nur einen Zustand einnimmt. Dann
kann es sein, dass der Compiler optimiert.
z.B.:
1
constintfestwert=10;
2
if(festwert<5)
3
a();
4
else
5
b();
Wenn er aber nicht weiß, was mit Variable passieren kann, wird er beide
Fälle und das if dazu übersetzen.
Dass muss aber keineswegs immer so sein. Was dein Compiler genau macht,
musst du nachlesen oder ausprobieren.
Minty Mint schrieb:> wie nun?
Also wenn du bis hier noch nicht den Unterschied zwischen Präprozessor
und Compiler mitbekommen hast, würde ich es dir nicht vorwerfen.
Aber daß du trotzdem bis jetzt immer noch nicht selbst angefangen hast
dich schlau zu machen, z.B. mit einem Buch, zeigt deutlich, daß es
einfach sinnlos ist dir hier alles vorzukauen.
Was es mit #if auf sich hat, ist erstens elementar für die
C-Programmierung, und zweitens genau deshalb in jedem C-Buch
beschrieben.
Wieso sollen die Leute sich hier mehr Mühe geben als du selbst - für
deine Interessen?
Und wie willst du weitermachen mit Programmieren? Bei jedem Pups hier
fragen und alles erklären lassen?