Warnung bei if (variable) bla();

Gast #7105215
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.
Moderator Persönliche Seite #7105267
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. ;-)
Gast #7105271
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...
Gast #7105284
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.
#7105293
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.
Gast #7105336
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.
#7105924
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).
#7106812
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...
Gast #7106820
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);
Gast #7106847
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.)
#7106879
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.
#7106914
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.
Gast #7107473
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
#7111569
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.
#7111813
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.
Moderator Persönliche Seite #7111876
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.
Gast #7113755
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
}
Moderator #7113792
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.
Gast #7113890
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.
Gast #7114980
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.
Gast #7115023
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.
Moderator Persönliche Seite #7115091
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren