Forum: Compiler & IDEs Wird if Schleife ignoriert, wenn sie nie eintritt?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Sim J. (unimetal)


Lesenswert?

Hallo,
angenommen ich möchte für Debugzwecke in einer Interruptroutine ein Flag 
setzen, welches in der Hauptschleife eine Serielle Ausgabe verursacht, 
wenn das Flag gesetzt wurde.
Wird die if Schleife im folgenden Fall vom Compiler ignoriert, sodass 
diese gar nicht erst in den Speicher des µC geladen wird (da debug = 
false)?
Es geht um typische C Compiler.

Ein anderer Fall. Wenn ich debug = true setze, trifft die if Anweisung 
ja immer zu. Findet dann eine rechenzeit kostende Abfrage statt oder 
Kürzt der Compiler die if-Abfrage komplett heraus?

In etwa so:
1
bool debug = false;
2
bool flag = false;
3
4
loop(){
5
   if (debug == true) {
6
   Serielle Ausgabe...;
7
   flag = false;
8
}
9
10
void INTERRUPT() {
11
   if (debug == true) {
12
   flag = true;
13
   }
14
}

Danke und Gruß

: Bearbeitet durch User
von au weia (Gast)


Lesenswert?

ja ja ... die If-Schleife .... jeden Tag wird wieder eine
(neue alte) Sau durchs Dorf getrieben ....

von au weia (Gast)


Lesenswert?

Sim J. schrieb:
> Es geht um typische C Compiler.

Nein, es geht um Arduino. Du darfst es schon sagen wie es ist.

von Bernd (Gast)


Lesenswert?


von Sim J. (unimetal)


Lesenswert?

Natürlich gehts um Arduino, sonst würde ich nicht so dumme Fragen 
stellen und alte Kühe durchs Dorf treiben. Ihr seid wahrscheinlich 
gelangweilt von derart trivialen Fragestellungen. Allerdings konnte ich 
auf die schnelle keinen alten Thread auffinden, in dem diese Frage 
gestellt wurde.

von Dunno.. (Gast)


Lesenswert?

Stichworte für Google : defines, preprocessor

#define und #ifdef

von Rainer U. (r-u)


Lesenswert?

Präprozessor-Direktiven sind das, was Du suchst (#define, #ifdef)

von au weia (Gast)


Lesenswert?

Sim J. schrieb:
> void INTERRUPT()

Funktions- und Variablen-Namen schreibt man nicht durchgängig
in Grossbuchstaben. Nein das tutet man nicht! Das ist für
Konstanten (Defines) vorbehalten und ist gängige Praxis bei
jedem C-Programmierer der nur einigermassen Anstand kennt.

von Adam P. (adamap)


Lesenswert?

Sim J. schrieb:
> Natürlich gehts um Arduino, sonst würde ich nicht so dumme Fragen
> stellen und alte Kühe durchs Dorf treiben.

Ihm ging es nicht um die Arduino Frage, sondern um die erwähnte 
"if-schleife"

http://if-schleife.de

---
Ich würde dir auch Präprozessor-Direktiven empfehlen:
1
#define DEBUG
2
3
void loop()
4
{
5
   #ifdef DEBUG
6
   Serial.println("...");
7
   #endif
8
}

Dann wird es entweder mitcompiliert oder nicht.

: Bearbeitet durch User
von Jack V. (jackv)


Lesenswert?

Sim J. schrieb:
> Allerdings konnte ich
> auf die schnelle keinen alten Thread auffinden, in dem diese Frage
> gestellt wurde.

Das mag auch an der falschen Terminologie gelegen haben: 
http://if-schleife.de/

von leo (Gast)


Lesenswert?

Sim J. schrieb:
> void INTERRUPT() {
>    if (debug == true) {

- Es gibt keine if-Schleife
- du willst den Sinn von "volatile" lernen
- und deine Flags und die Logik dahinter entwirren

leo

von Schlaumaier (Gast)


Lesenswert?

Es würde mich wundern wenn Compiler so intelligent sind.

von Sim J. (unimetal)


Lesenswert?

Danke für die Hinweise mit den Präprozessor direktiven.
Danke auch für den Hinweis mit der GROSSSCHREIBUNG. Das klingt sinnig 
für mich!

von Joachim B. (jar)


Lesenswert?

Sim J. schrieb:
> Ihr seid wahrscheinlich
> gelangweilt von derart trivialen Fragestellungen.

nö nur amüsiert die "if schleife"

Du wirst also schon einiges gelesen haben, leider auch FALSCHES, zeige 
wo es deine if schleife geben soll!

Es gibt Schleifen!
Es gibt If Abfragen!

If Schleifen gibt es nicht!!!!! merken 1000x aufschreiben.

Sim J. schrieb:
> Hallo,
> angenommen ich möchte für Debugzwecke in einer Interruptroutine ein Flag
> setzen

tu das
volatile boolean merker=false;
IRQ merker = true;
if merker == true machwas();

: Bearbeitet durch User
von Adam P. (adamap)


Lesenswert?

Joachim B. schrieb:
> If Schleifen gibt es nicht!!!!! merken 1000x aufschreiben.

Nunja :-D

Ich hatte das mal in C umgeschrieben, aber wie gesagt, BITTE NICHT SO 
MACHEN!

http://blog.ebene7.com/2010/01/15/und-es-gibt-sie-doch-if-schleifen-so-wird-es-nicht-gemacht/

Hoffe ihr steinigt mich jetzt nicht.

von Schlaumaier (Gast)


Lesenswert?

au weia schrieb:
> Funktions- und Variablen-Namen schreibt man nicht durchgängig
> in Grossbuchstaben. Nein das tutet man nicht! Das ist für
> Konstanten (Defines) vorbehalten und ist gängige Praxis bei
> jedem C-Programmierer der nur einigermassen Anstand kennt.

Ein guter Editor schreibt die Automatisch richtig. Und die besseren 
malen Sie sogar noch an.

Über so was habe ich mich seit min. 10 Jahren nicht mehr gekümmert.

von Frank (Gast)


Lesenswert?

Adam P. schrieb:
> Ich hatte das mal in C umgeschrieben, aber wie gesagt, BITTE NICHT SO
> MACHEN!
> 
http://blog.ebene7.com/2010/01/15/und-es-gibt-sie-doch-if-schleifen-so-wird-es-nicht-gemacht/
> Hoffe ihr steinigt mich jetzt nicht.

Auch das ist keine Schleife, sondern eine Abfrage auf die ein 
Sprungbefehl folgt.

von Adam P. (adamap)


Lesenswert?

Frank schrieb:
> Auch das ist keine Schleife, sondern eine Abfrage auf die ein
> Sprungbefehl folgt.

Ja...hast recht! Fands nur amüsant.

von Oliver S. (oliverso)


Lesenswert?

Um das auch mal zu beantworten:

Sim J. schrieb:
> Wird die if Schleife im folgenden Fall vom Compiler ignoriert, sodass
> diese gar nicht erst in den Speicher des µC geladen wird (da debug =
> false)?

> Ein anderer Fall. Wenn ich debug = true setze, trifft die if Anweisung
> ja immer zu. Findet dann eine rechenzeit kostende Abfrage statt oder
> Kürzt der Compiler die if-Abfrage komplett heraus

Der Compiler kürzt bei Compilierung mit Optimierung zur Compilezeit 
bekannte Bedingungen heraus, und entfernt ungenutzen Code, wenn der 
eindeutig ungenutzt ist. Bei ersterem ist dafür ein const oder constexpr 
vor dem bool hilfreich.

#define braucht es für sowas in C++ nicht, das brauchts nur in C.

Oliver

von Roland E. (roland0815)


Lesenswert?

Schlaumaier schrieb:
> Es würde mich wundern wenn Compiler so intelligent sind.

Je nach Qualität des Compilers fliegen nie erreichte Codeschnipsel (nach 
einer Warnung) bei höheren Optimierungsstufen tatsächlich raus. Das og 
Konstrukt mit den Konstanten ist so ein Fall.

von Oliver S. (oliverso)


Lesenswert?

Schlaumaier schrieb:
> Es würde mich wundern wenn Compiler so intelligent sind.

Es würde dich noch mehr wundern, wenn du wüsstest, wieviel Aufwand die 
Compilerbauer in die Optimierungen gesteckt haben und immer noch 
stecken, und was die alles können.

Ungennutzen Code entfernen ist allerdings eine der Basis-Optimierungen 
überhaupt, das gibt es schon seit ewigen Zeiten.

Oliver

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Sim J. schrieb:
> Wird die if Schleife im folgenden Fall vom Compiler ignoriert, sodass
> diese gar nicht erst in den Speicher des µC geladen wird (da debug =
> false)?

Nö.
Er kann ja nicht wissen, ob die Variable nicht in einer anderen 
Compile-Unit
geändert wird.
Du müßtest sie schon als static deklarieren.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Sim J. schrieb:
> Wenn ich debug = true setze, trifft die if Anweisung ja immer zu. Findet
> dann eine rechenzeit kostende Abfrage statt oder Kürzt der Compiler die
> if-Abfrage komplett heraus?

Mal was zum Thema:

Wenn der Compiler mit einer entsprechenden Optimierungs-Option (-O bzw. 
-O2) gestartet wurde, kann er solche if-Abfragen schon wegoptimieren- 
sowohl wenn debug == true oder debug == false gesetzt wird.

Allerdings musst Du ihm schon etwas unter die Arme greifen, indem Du ihm 
sagst, dass auf die Variable debug nur in dieser Übersetzungseinheit 
zugegriffen wird und nicht ausserhalb. Das geht mit dem Zauberwort 
"static":
1
static bool debug = false;

Dann kann der Compiler - wenn er schlau genug ist - die if-Abfragen 
komplett wegoptimieren, da er sieht, dass sich die Variable "debug" 
nicht ändern kann. Wenn Du das "static" weglässt, muss der Compiler 
davon ausgehen, dass die Variable extern geändert werden kann, da er 
jede Übersetzungseinheit für sich getrennt sieht. In diesem Fall kann er 
die if-Abfragen nicht wegoptimieren. Ausnahme ist LTO - aber das ist 
wieder ein ganz anderes Thema.

Welcher Compiler das kann und ab welchem Optimierungslevel er das tut, 
kann man nicht pauschal sagen. Im Zweifel sollte man sich das 
Assemblerlisting anschauen. Ich bin mir aber ziemlich sicher, dass der 
gcc das ab -O kann, vorausgesetzt, Du hast diese Variable auch static 
definiert.

Ein ganz anderes Thema ist Deine Interupt-Funktion. Im Allgemeinen muss 
eine Variable "volatile" definiert werden, wenn auf sie innerhalb und 
außerhalb einer Interrupt-Funktion zugegriffen wird.

Fazit:
Verwende die vorgeschlagene Preprozessor-Variante. Diese funktioniert 
immer und ist nicht vom Gutdünken des verwendeten Compilers abhängig.

P.S.
Leider machen viele Programmierer viel zu wenig von dem Typenbezeichner 
"static" Gebrauch. Auch Funktionen, die nur innerhalb der 
Übersetzungseinheit (C- oder C++-Datei) aufgerufen werden, sollte man 
static definieren. In diesem Fall kann der Compiler unter Umständen auch 
Funktionsaufrufe eliminieren oder inlinen.

von Forenverzweifler (Gast)


Lesenswert?

Leider ist der Umgangsstil in diesem Forum echt unter jeder Sau.

Oliver S. schrieb:
> Um das auch mal zu beantworten:

Danke, dass du im 18. Beitrag dieses Threads als erster fachkompetent 
antwortest.

Ich möchte noch hinzufügen, das man das mit etwas Übung am besten im 
Assembler-Code nachschauen kann.

Die Frage, wann ein Compiler erkennt, dass ein Code nicht im Execution 
Path liegt, ist nämlich nicht immer trivial - hier kommen auch die 
"volatile"-Variablen ins Spiel, die manche genannt haben. Ausserdem 
kommt es natürlich auf die Compiler-Flags an.

von Joachim B. (jar)


Lesenswert?

Forenverzweifler schrieb:
> Leider ist der Umgangsstil in diesem Forum echt unter jeder Sau.

genial ein Rundumschlag an ALLE!

Forenverzweifler schrieb:
> Danke, dass du im 18. Beitrag dieses Threads als erster fachkompetent
> antwortest.

und zählen kannst du auch nicht, oder erkläre mir was an der 13ten 
Antwort fachlich falsch war.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.