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'.
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
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. ;-)
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...
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
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 😂
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.
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.
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).
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
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
intvariable;
3
intmain(){
4
if(variable)printf("test");
5
}
gibt keine Warnung,
bei Änderung auf:
1
#include<stdio.h>
2
intvariable[42];
3
intmain(){
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]
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.)
DerEgon schrieb:> Nun könnte "variable" aber auch ein Funktionsparameter und keine> statische Variable sein, und schon geht's nicht mehr.>>
1
>intvariable[4];
2
>
3
>voidtest(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
booltest(int*p){
2
if(p){
3
p[0]=42;
4
returntrue;
5
}
6
else{
7
// do not use p;
8
returnfalse;
9
}
Wenn keine "nullable-reference" für die Funktion gemeint ist, dann muss
man das auch schreiben:
1
voidtest(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.
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 …
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
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.
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.
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.phphttps://github.com/danmar/cppcheck/blob/main/addons/misra.py
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.
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
voidf(constchar*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
voidf(constchar*constname){
2
// ...
3
constchar*constbasename=(name+prefixlength);
4
// ...
5
g(basename);
6
}
Das ist für den oftmals flüchtigen Leser des Codes wesentlich besser.
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.
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:
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.
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.
> 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.
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.
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.