Forum: Compiler & IDEs Warnung bei if (variable) bla();


von Ingo (Gast)


Lesenswert?

Hallo,

gibt es einen -W... Schalter, der mir bei sowas hier (wegen Faulheit zum 
Tippen) Warnungen auswirft?
1
if (variable) bla();

variable kann ja int variable sein, dann sollte aber trotzdem verlangt 
werden, dass ich
1
if (variable != 0) bla();

schreibe. Oder variable ist int variable[n], dann wäre das o.g. ja 
sowas:
1
if (variable != NULL) bla();

Gemeint ist aber eventuell das hier:
1
if (variable[0] != 0) bla();

Nur kommt halt keine Warnung.

von MaWin (Gast)


Lesenswert?

Ingo schrieb:
> gibt es einen -W... Schalter

Vielleicht. Hängt vom Compiler ab, den du zu verwenden gedenkst. Und 
Überraschung: es gibt mehr als Einen.

Ingo schrieb:
> Gemeint ist aber eventuell das hier:

Da variable da nicht NULL sein kann, kann es eine Warnung geben 
'condition always true'.

von Ingo (Gast)


Lesenswert?

gcc
Version... die beim ESP32 IDF 4.4.1 dabei ist.

von Oliver S. (oliverso)


Lesenswert?

Ingo schrieb:
> Nur kommt halt keine Warnung.

Du bräuchtest sowas wie -WcurrentlyUsingC : „warning: using C language 
is highly risky if not done properly. Use at your own risk“.

Die ist aber erst für gcc 42 vorgesehen.

Oliver

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Erstens: "if (variable)" (wenn sie vom Typ "int" ist) ist völlig 
identisch zu "if (variable != 0)". Die Auswertung der Bedingung erzeugt 
ja wiederum einen Ausdruck vom Typ "int", wie soll der Compiler also für 
den gleichen Typ einmal eine Warnung generieren und das andere Mal 
nicht?

Zweitens: nein, ein Array ist was anderes als ein Zeiger.

Ich denke, du suchst eine andere Programmiersprache als C. ;-)

von Michael (Gast)


Lesenswert?

Da sieht man Mal, wie unterschiedlich die Geister sind.

Bei C# rege ich mich immer auf "!= 0" tippen zu müssen. Besonders bei 
enums ist das richtig hässlich.

Aber ich will mich nicht beschweren, wenigstens hat C# die Syntax für 
die Variablendeklaration und Pointer von C übernommen und nicht diesen 
":"-Irrsinn der "modernen" Sprachen.

Also Ingo: Nimm C# dann wirst du glücklich...

von Ingo (Gast)


Lesenswert?

Mh, ne, ich muss einen umfangreichen fremden Code erweitern. Einige 
Variablen werden zu Arrays, natürlich überall im Code und da steht eben 
wirklich oft
1
if (variable) ...

Die fehlende Warnung ist wirklich schade.

von Heiner (Gast)


Lesenswert?

Oliver S. schrieb:
> Ingo schrieb:
>> Nur kommt halt keine Warnung.
>
> Du bräuchtest sowas wie -WcurrentlyUsingC : „warning: using C language
> is highly risky if not done properly. Use at your own risk“.
>
> Die ist aber erst für gcc 42 vorgesehen.
>
> Oliver

YMMD 😂

von (prx) A. K. (prx)


Lesenswert?

Ingo schrieb:
> Oder variable ist int variable[n], dann wäre das o.g. ja
> sowas:
> if (variable != NULL) bla();
>
> Gemeint ist aber eventuell das hier:
> if (variable[0] != 0) bla();

Dafür könnte es etwas geben, weil die Adresse eines solchen Arrays nie 
NULL sein kann. Manche Compiler könnten, wenn dazu aufgefordert, darauf 
hinweisen.

: Bearbeitet durch User
von Lars F. (flemmy)


Lesenswert?

Statt des Compilers hilft dir evtl. ein Tool zur statischen Code 
Analyse.

von Dirk B. (dirkb2)


Lesenswert?

Sonst such mal mit einer RegExp im Code

von A. S. (Gast)


Lesenswert?

Ingo schrieb:
> . Einige Variablen werden zu Arrays, natürlich überall im Code und da
> steht eben wirklich oft
> if (variable) ...
>
> Die fehlende Warnung ist wirklich schade.

Das Problem nimmt Dir die Warnung nicht ab: Einen Unterschied von Nil, 
nul, null und 0 gibt es nicht.

Wenn also überall !=0 steht, erkennt trotzdem niemand ein fehlendes [x].

Wenn man im Code nicht weiß, ob man eine Variable oder ein Array hat, 
ein Datenfeld oder einen ptr, und den Inhalt auswertet (also nicht nur 
das Objekt weiterreicht), dann könnte das rechte Verständnis lande 
dauern.

Abhilfe für Dein Problem schaffen nur statische Code-Analyse-tools und 
hohe Disziplin.

von Wilhelm M. (wimalopaan)


Lesenswert?

Ingo schrieb:
> Hallo,
>
> gibt es einen -W... Schalter, der mir bei sowas hier (wegen Faulheit zum
> Tippen) Warnungen auswirft?
>
>
1
if (variable) bla();

Warum sollte da eine Warnung kommen?

> variable kann ja int variable sein, dann sollte aber trotzdem verlangt
> werden, dass ich
>
>
1
if (variable != 0) bla();

Nein.

> schreibe. Oder variable ist int variable[n], dann wäre das o.g. ja
> sowas:
>
>
1
if (variable != NULL) bla();

Nein

>
> Gemeint ist aber eventuell das hier:
>
>
1
if (variable[0] != 0) bla();
>
> Nur kommt halt keine Warnung.

Genau.
Der Compiler kann ja nicht raten, was Du willst.
C/C++ ist (noch) nicht: WYMIWYG (what you mean is what you get).

von Oliver S. (oliverso)


Lesenswert?

A. S. schrieb:
> Abhilfe für Dein Problem schaffen nur statische Code-Analyse-tools und
> hohe Disziplin.

Wobei ziemlich gute tools für statische Code-Analyse heutzutage die 
Compiler selber sind.

Oliver

von DerEgon (Gast)


Lesenswert?

cppcheck ist recht gut.

https://cppcheck.sourceforge.io/

Oder das hier


https://www.viva64.com/en/pvs-studio/

In jede zu testende Datei diesen Kommentar einfügen:
1
// This is a personal academic project. Dear PVS-Studio, please check it.
2
3
// PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com

von Εrnst B. (ernst)


Lesenswert?

Ingo schrieb:
> Einige
> Variablen werden zu Arrays, natürlich überall im Code und da steht eben
> wirklich oft
> if (variable) ...
>
> Die fehlende Warnung ist wirklich schade.

Häh? Genau bei diesem Fall gibt der Compiler doch eine Warnung aus...
d.H. der Compiler macht doch bereits exakt das, was du willst?
1
#include <stdio.h>
2
int variable;
3
int main() {
4
    if (variable) printf("test");
5
}

gibt keine Warnung,
bei Änderung auf:
1
#include <stdio.h>
2
int variable[42];
3
int main() {
4
    if (variable) printf("test");
5
}

gibt's ein
1
<source>: In function 'main':
2
<source>:4:9: warning: the address of 'variable' will always evaluate as 'true' [-Waddress]
3
    4 |     if (variable) printf("test");

um die Ohren...

von DerEgon (Gast)


Lesenswert?

Nun könnte "variable" aber auch ein Funktionsparameter und keine 
statische Variable sein, und schon geht's nicht mehr.
1
int variable[4];
2
3
void test(int *p)
4
{
5
  if (p)
6
  {
7
    //bla
8
  }
9
10
  if (p[0])
11
  {
12
    //bla
13
  }
14
}
15
16
...
17
18
test(variable);

von NichtWichtig (Gast)


Lesenswert?

Zudem gibt es sinnvolle Regeln bei den Namen von Variablen.

Anhand derer kann man den Unterschied von int oder array schon sehen.

von Nachdenklicher (Gast)


Lesenswert?

NichtWichtig schrieb:
> Zudem gibt es sinnvolle Regeln bei den Namen von Variablen.
>
> Anhand derer kann man den Unterschied von int oder array schon sehen.

Du möchtest jetzt nicht allen Ernstes den Zombie namens ungarische 
Notation (https://de.wikipedia.org/wiki/Ungarische_Notation) wieder 
freilassen, oder?

Einfache Regeln wie "skalare mit Singular-Namen, Arrays mit 
Plural-Namen" funktionieren halt nur bei Begriffen, bei denen sich 
Singular und Plural unterscheiden. Versuch das mal mit "Fenster". (Ja, 
deutsche Bezeichner sind 🤢, aber im Englischen geht das mit anderen 
Begriffen genauso. Ist in einem deutschsprachigen Forum daher 
augenfälliger.)

von Wilhelm M. (wimalopaan)


Lesenswert?

DerEgon schrieb:
> Nun könnte "variable" aber auch ein Funktionsparameter und keine
> statische Variable sein, und schon geht's nicht mehr.
>
>
1
> int variable[4];
2
> 
3
> void test(int *p)
4
> {
5
>   if (p)
6
>   {
7
>     //bla
8
>   }
9
> 
10
>   if (p[0])
11
>   {
12
>     //bla
13
>   }
14
> }
15
> 
16
> ...
17
> 
18
> test(variable);
19
>

Was soll hier nicht mehr gehen?

Zeiger sind "nullable-references": die Signatur sagt also klar aus, dass 
die Funktion test(int* p) mit dem inout-Parameter p auch nullptr 
akzeptiert. Das checked-pointer-idiom ist also vollkommen richtig.

Wobei Dein Code falsch ist. Es müsste heißen:
1
bool test(int* p) {
2
    if(p) {
3
        p[0] = 42;
4
        return true;
5
    }  
6
    else {
7
        // do not use p;
8
        return false;
9
    }

Wenn keine "nullable-reference" für die Funktion gemeint ist, dann muss 
man das auch schreiben:
1
void test(int& p) {
2
    p = 42;
3
}

Vielleicht hat der TO aber auch nicht verstanden, dass in den meisten 
Kontexten der Bezeichner eines Arrays zu einem Zeiger zerfällt (decay).
Aber auch das kann man sinnvoll vermeiden, in dem man das decay eben 
vermeidet.
Man sollte halt schon wissen, was man schreibt. Und der Compiler macht 
genau das, was man hinschreibt.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Wilhelm M. schrieb:
> Wenn keine "nullable-reference" für die Funktion gemeint ist, dann muss
> man das auch schreiben:

Das ist C++ (only). Gut, der TE schrieb nicht dazu, um welche Sprache es 
geht …

von Oliver S. (oliverso)


Lesenswert?

Wilhelm M. schrieb:
> Was soll hier nicht mehr gehen?

Das, um was es in diesem Thread eigentlich ging:

eine Warnung auch bei syntaktisch richtigem Code, wenn der TO als 
Codeautor eigentlich was ganz anders wollte, als er hingeschrieben hat.

Oliver

von Wilhelm M. (wimalopaan)


Lesenswert?

Oliver S. schrieb:
> Wilhelm M. schrieb:
>> Was soll hier nicht mehr gehen?
>
> Das, um was es in diesem Thread eigentlich ging:
>
> eine Warnung auch bei syntaktisch richtigem Code, wenn der TO als
> Codeautor eigentlich was ganz anders wollte, als er hingeschrieben hat.

Ok, wie ich oben schon mal sagte: "what you mean is what you get" ist 
derzeit erst für gcc Version 42 geplant.

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Wobei es natürlich schon sein kann, dass statische Codeanalyse-Tools 
auch abseits der Syntax entsprechende stilistische Überprüfungen 
vornehmen können. Typischer Anwendungsfall: MISRA-Überprüfungen, bei 
denen ja sehr viele Einschränkungen angewendet werden. Ist die Frage, ob 
man sowas auch kostenlos bekommt.

von Kaj (Gast)


Lesenswert?

Jörg W. schrieb:
> MISRA-Überprüfungen, bei
> denen ja sehr viele Einschränkungen angewendet werden. Ist die Frage, ob
> man sowas auch kostenlos bekommt.
Cppcheck kann (auf Kommandozeile) MISRA, und sagt einem gegen welche 
Regeln verstoßen werden. Den text zu den Regeln gibt Cppcheck aber nicht 
aus, da der Regeltext halt kostenpflichtig ist. Aber man kann auch 
eigene Texte zu jeder Regel anlegen. Cppcheck gibt es auch in der 
kostenpflichtigen Premium Version.

http://cppcheck.net/misra.php

https://github.com/danmar/cppcheck/blob/main/addons/misra.py

von Kaj (Gast)


Lesenswert?

Kaj schrieb:
> Cppcheck kann (auf Kommandozeile) MISRA

Aufruf mit:
1
cppcheck --addon=misra.py somefile.c
http://cppcheck.net/manual.html#running-addons

von Kaj (Gast)


Lesenswert?

Kaj schrieb:
> Den text zu den Regeln gibt Cppcheck aber nicht
> aus, da der Regeltext halt kostenpflichtig ist.

https://sourceforge.net/p/cppcheck/discussion/general/thread/ccbe9e89/

von Ein Kommentar (Gast)


Lesenswert?

> eine Warnung auch bei syntaktisch richtigem Code

Wo wir gerade bei dem Thema sind - ich will eine Warnung bei
1
if (variable = 0) bla();

von (prx) A. K. (prx)


Lesenswert?

Ein Kommentar schrieb:
> ich will eine Warnung bei

Ist in -Wall drin.

von Zählererbse (Gast)


Lesenswert?

Warnung sind zum ignorieren da

von Wilhelm M. (wimalopaan)


Lesenswert?

Ein Kommentar schrieb:
>> eine Warnung auch bei syntaktisch richtigem Code
>
> Wo wir gerade bei dem Thema sind - ich will eine Warnung bei
>
>
1
if (variable = 0) bla();

Bekommst Du, wenn variable sinnvollerweise read-only ist:
1
const int variable = <expression>;

von Oliver S. (oliverso)


Lesenswert?

Wilhelm M. schrieb:
> variable

heisst wohl nicht ganz umsonst so.

Oliver

von Εrnst B. (ernst)


Lesenswert?

Wilhelm M. schrieb:
> Bekommst Du, wenn variable sinnvollerweise read-only ist:

Die Warnung bekommst du bei "read-write"-Variablen. Man muss die 
Warnungen nur anschalten. Bei "const" ist's ein Fehler, und keine 
Warnung.

Zählererbse schrieb:
> Warnung sind zum ignorieren da

Nachdem wir im Laufe dieses Threads so viele neue und innovative 
Warnungen in den GCC eingebaut haben (Sogar rückwirkend in alte 
Versionen! Zeitmaschine!), hätte ich da noch eine radikale Idee:

Einen Schalter, dass Warnungen wie Fatale Fehler behandelt werden, damit 
man sie nicht mehr ignorieren kann.
Diesen Switch könnte man dann vielleicht "-Werror" nennen.

von Wilhelm M. (wimalopaan)


Lesenswert?

Oliver S. schrieb:
> Wilhelm M. schrieb:
>> variable
>
> heisst wohl nicht ganz umsonst so.

Der Name (softwaretechnische) "Variable" für ein "benanntes Objekt" ist 
historisch wie viele Dinge, will sagen, trifft also nicht mehr ganz ins 
Ziel, und hat ja je nach Kontext unterschiedliche Bedeutungen (z.B. != 
mathem. Variable).

Zudem sollten möglichst alle "Variablen" read-only sein, damit ein 
schleichender Bedeutungswechsel in ihrem Gültigkeitsbereich 
ausgeschlossen ist. Ganz besonders wichtige Kandidaten dafür sind etwa 
die Parametervariablen einer Funktion. Man braucht auch nicht der 
Meinung zu sein, dass Einführen weiterer read-only Variablen für 
errechnete Werte bringe Nachteile: der Compiler wird es entsprechend 
optimieren.

Klassiker:
1
void f(const char* name) {
2
   // ...
3
   name += 3; // <1>
4
   // ...
5
   g(name);
6
}

Ab <1> ist name eben nicht mehr der vollständige Name, sondern der 
Name-ohne-Prefix. Das ist eine Bedeutungswechsel der Variablen name.

Daher besser:
1
void f(const char* const name) {
2
   // ...
3
   const char* const basename = (name + prefixlength);
4
   // ...
5
   g(basename);
6
}

Das ist für den oftmals flüchtigen Leser des Codes wesentlich besser.

von A. S. (Gast)


Lesenswert?

Ein Kommentar schrieb:
> Wo wir gerade bei dem Thema sind - ich will eine Warnung bei
> if (variable = 0) bla();
Disziplin
1
   if (0 = variable) bla();

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

A. S. schrieb:
> Disziplin

Davon abgesehen, dass ich die Lesbarkeit bescheiden finde (wir sagen 
schließlich "Wenn a gleich 5 ist" und nicht "Wenn 5 gleich a ist"), 
hilft dir das spätestens dann nicht mehr, wenn du a und b vergleichen 
musst. Die Compilerwarnung für das einfache Gleichheitszeichen, die wohl 
mittlerweile jeder Compiler beherrscht, hilft dir dagegen auch dann 
noch.

von M. Н. (Gast)


Lesenswert?

A. S. schrieb:
> Ein Kommentar schrieb:
>> Wo wir gerade bei dem Thema sind - ich will eine Warnung bei
>> if (variable = 0) bla();
> Disziplin   if (0 = variable) bla();

Hast ein = vergessen :)

Haben wir auf der Arbeit dank Misra auch mal so gemacht. Nach 5 Jahren 
coden in diesem Style kann ich sagen: Es ist viel schlechter und 
anfälliger, als es in "Denkrichtung" zu schreiben. Keiner denkt so und 
das ist anfällig. Vor allem, wenn noch < und > Operatoren dazukommen.

Warnungen einschalten und eine "Zero-Warning-Policy" leben, und dann ist 
es eigentlich kein Problem. Ich code seit Jahren in C und das fehlende = 
im Vergleich war nie ein Problem, solange man seine Warnungen 
durchschaut.

Code muss lesbar sein. 20% der Zeit werden beim coden investiert und 80% 
der Zeit wird Code gelesen.

A. S. schrieb:
> if (0 = variable) bla();

Viel schlimmer finde ich den fehlenden Zeilenumbruch nach dem if. Sowas 
mache ich nur, wenn ich was gut verstecken will ;)

Ich mache es abhängig von der "Art" der Variable:

Ich würde schreiben:
1
...
2
if (number_received_frames == 0) {
3
        /* Do some stuff */
4
}
Aber andererseits bei "bool-artigen" Variablen, die einen ja/nein, 
wahr/falsch Zustand ausdrücken:
1
if (tx_frontend_enabled) {
2
      /* Do some stuff */
3
}

von Yalu X. (yalu) (Moderator)


Lesenswert?

Wilhelm M. schrieb:
> Oliver S. schrieb:
>> Wilhelm M. schrieb:
>>> variable
>>
>> heisst wohl nicht ganz umsonst so.
>
> Der Name (softwaretechnische) "Variable" für ein "benanntes Objekt" ist
> historisch wie viele Dinge, will sagen, trifft also nicht mehr ganz ins
> Ziel,

IMHO tut er das immer noch. Eine const-Variable kann zwar nicht
überschrieben werden, aber bei jeder Instanziierung einen anderen Wert
annehmen.

In der funktionalen Programmierung heißen die Dinger ebenfalls
Variablen, obwohl sie dort schon seit jeher implizit "const" sind. Der
Begriff wurde dort aus der Mathematik übernommen, wo es ebenfalls keine
Zuweisungen an Variablen gibt. x=x+1 bedeutet in der Mathematik nicht
"erhöhe x um 1", sondern ist entweder einer Gleichung oder (wie auch in
der FP) eine rekursive Definition.

von A. S. (Gast)


Lesenswert?

M. H. schrieb:
> Es ist viel schlechter und
> anfälliger, als es in "Denkrichtung" zu schreiben. Keiner denkt so und
> das ist anfällig.

Ich würde nie im Leben so programmieren. Ich bin ein Freund scharfer 
Warnungen und bei mir springen da mehrere an.

Das Beispiel dienste lediglich der Vervollständigung der Möglichkeiten 
militanter Naturburschen, nachdem "Warnung einschalten" ja schon genannt 
wurde.

Wer heute auf sowas reinfällt reißt wohl auch als erstes Airbag und 
Sicherheitsgurte aus dem Auto um Gewicht zu sparen.

von Eine Anmerkung (Gast)


Lesenswert?

> Ich würde nie im Leben so programmieren.

Genau hier liegt das Problem. Programmierer haben keine Disziplin. Jeder 
macht das, was er selbst aus seinem Bauch heraus als das beste erachtet.

In allen anderen technischen Bereichen hat sich die Vorgehensweise der 
Ingenieure durchgesetzt.

Ein Bauingenieur, der statische Berechnungen erstellt, kommt gar nicht 
auf die Idee, er wolle aus seiner persönlichen Auffassung heraus selbst 
entscheiden, wie er seine Berechnungen anlegt. In der DIN Normen ist 
klar definiert, welchen Umfang die Berechnung hat, auf was er achten 
muss, wer seine Arbeit überprüft und auf was der Prüfingenieur achten 
muss. In der DIN ist sogar festgelegt, welch Namen der Statiker für 
seine Variablen verwenden muss.

Programmierer dagegen sind alles Ignoranten und Chaoten. Du glaubst du 
bräuchtest keine DIN Normen. Könntest die Erfahrungen deiner Vorgänger 
ignorieren und einfach so aus deinem Bauchgefühl heraus selbst 
entscheiden, welche Warnungen erforderlich sind.

von Mombert H. (mh_mh)


Lesenswert?

Eine Anmerkung schrieb:
> Ein Bauingenieur, ...

Das hört sich so an als wäre die Arbeit der Bauingenieure equivalent zu 
Malen nach Zahlen.

von MaWin (Gast)


Lesenswert?

Eine Anmerkung schrieb:
> Ein Bauingenieur, der statische Berechnungen erstellt, kommt gar nicht
> auf die Idee, er wolle aus seiner persönlichen Auffassung heraus selbst
> entscheiden, wie er seine Berechnungen anlegt.

Ach? Ist das so? Ich glaube nicht.

Ein Softwareentwickler kommt auch nicht auf die Idee die Mathematik nach 
seiner persönlichen Auffassung zu interpretieren.
Beim Schreiben des Programms hat er gewisse Freiheiten. Genau wie der 
Bau-Ing seine Freiheiten beim Aufschreiben und Durchführen der 
Berechnungen hat.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Eine Anmerkung schrieb:
> Genau hier liegt das Problem.

Das Problem bei dieser Schreibweise liegt daran, dass sie aus Zeiten 
stammt, da Compiler den Fehler noch nicht gewarnt haben. Das ist 20+ 
Jahre her, aber seither hat sie sich bei einigen festgesetzt als "das 
ist so sicherer".

Warum diese Schreibweise das Problem sowieso nicht lösen kann, habe ich 
oben argumentiert. Aber du argumentierst lieber mit "Disziplin". Wir 
sind hier aber nicht bei der Armee, wo Befehle nach Disziplin ausgeführt 
werden müssen, sondern Programmierer müssen eigenständiges Denken 
anwenden. Das unterscheidet sie von Soldaten.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.