expertenaustausch > comp.lang.* > comp.lang.c

Helmut Schellong (04.01.2019, 19:40)
Gemeint sind Warnungen, die vor eventuellen Irrtümern warnen:
daß anstelle einer Zuweisung (=) eine Gleichheitsprüfung (==)
gemeint ist, oder daß die Operatorenränge von & | && ||
verwechselt wurden.

Ausgangsbasis ist:

,------------------------------------------------------
|if (mode==RV_ANMI && (p=sp) && p->vsp && !p->otyp &&
| p->ln==ln && !memcmp(p->name,name,ln)) return p;
'------------------------------------------------------

wo der Compiler (p=sp) anprangerte, das könne eine
falsche Zuweisung sein.
Der ältere Compiler meckerte an etwa 150 solchen Stellen.

Ich hatte daraufhin überall eine _semantische_ Änderung
gezielt vorgenommen: (a=b) --> (a=b,a)
die dem Compiler den Grund zur Warnung wegnahm.

Die Folge dieser Änderung war ein Shitstorm - wie üblich:
---------------------------------------------------------
o Ich hätte den Code _verkompliziert_
o um die Compiler-Analyse _auszutricksen_
o Meine Änderung sei überflüssig
o "Aha, statt p=sp in eine sinnvolle Anweisung unzuwandeln
suchst Du nach einer anderen unsinnigen Anweisung, die
zufälligerweise keine Warnung verursacht."
'p=sp' ist also unsinnig.
'(p=sp,p)' ist ebenfalls unsinnig.
'(p=sp,p)' löst _zufällig_ keine Warnung aus.
o "Oh, du bist aber kreativ. Compilerwarnungen durch Seiteneffekte
abstellen! Meine Fresse! Respekt. Darauf muß man erstmal kommen.
Zumal Compilerwarnungen normalerweise nicht zum Spaß eingebaut
werden."
o "Und hast offenbar nicht kapiert, was ich mir schon als absoluter
C Anfänger nach der ersten Beschreibung des ,-Ops im K&R 2ndEd
hinter die Ohren tätowiert habe: beim ','-Operator ist _NICHTS_
bzgl. der *Reihenfolge* der Auswertung definiert!"
o "Wenn ein C-"Laie" wie ich solche massiven Anfängerfehler in
deinen minimalen Auszügen aus deinem ... findet, dann will ich"
o Ich wäre daher nun der zweite C-Buch-Autor, der keine Ahnung hat,
der 'void main(void)' propagiert.
---------------------------------------------------------

Ich hingegen bin der Meinung, daß meine Änderung eine von mehreren
in C gültigen Maßnahmen ist, um einer solchen Warnung den Grund
zu nehmen. Meiner Meinung nach sogar die beste aller Möglichkeiten.

Und diejenigen, die den Shitstorm betrieben haben, haben nun
wahrlich keine große C-Kompetenz, bis hin zu vollkommener Fehlleitung.
Diese Leute (Inkompetenz unter sich) gewinnen aber und bedanken
sich gegenseitig für ihre auf Nichtwissen beruhenden Beiträge.

Ich hatte _vor_ dem Shitstorm sogar den C-Standard passend zitiert.
Hatte allerdings nichts genützt - so wie fast immer.

Ich schätze, in dieser Newsgroup kann kompetenter und professioneller
mit diesem Thema umgegangen werden.
Rainer Weikusat (04.01.2019, 20:15)
Helmut Schellong <rip> writes:
[..]
> Die Folge dieser Änderung war ein Shitstorm - wie üblich:
> ---------------------------------------------------------
> o Ich hätte den Code _verkompliziert_


Dem ist allerdings zuzustimmen: (a = b, a) ist komplizierter als (a =
b).

> o um die Compiler-Analyse _auszutricksen_


Das wuerde ich nicht so sehen: Die Warnung soll auf moegliche
Verwechslungen von == und = hinweisen. Fuer (a = b) ist dass gegeben,
fuer (a = b, a) nicht, weil (a == b, a) keinen Sinn haette (es ist
gleichwertig zu a).

[...]

> o "Und hast offenbar nicht kapiert, was ich mir schon als absoluter
> C Anfänger nach der ersten Beschreibung des ,-Ops im K&R 2ndEd
> hinter die Ohren tätowiert habe: beim ','-Operator ist _NICHTS_
> bzgl. der *Reihenfolge* der Auswertung definiert!"


The left operand of a comma operator is evaluated as a void
expression; there is a sequence point after its evaluation. Then
the right operand is evaluated; the result has its type and
value.
[6.5.17|2]

Das kann auch gar nicht anders sein, denn der Zweck von , ist es, einen
Ausdruck auszuwerten, nachdem eine Folge von Ausdruecken mit
Seiteneffekten ausgewertet wurden.

[...]

> Ich hingegen bin der Meinung, daß meine Änderung eine von mehreren
> in C gültigen Maßnahmen ist, um einer solchen Warnung den Grund
> zu nehmen.


Dem wuerde ich zustimmen.

> Meiner Meinung nach sogar die beste aller Möglichkeiten.


Allerdings halte ich es fuer besser, unsinnige Warnungen zu ignorieren,
als um sie herumzuhacken insofern das moeglich ist: Muss man mit Leuten
zusammenarbeiten, denen Compilerausgaben grundsaetzlich als hoehere
Wahrheit gelten, bleibt einem nichts anderes uebrig, als manche gezielt
zu unterbinden.
Juergen Ilse (04.01.2019, 21:25)
Hallo,

Helmut Schellong <rip> wrote:
[..]
> Ich hatte daraufhin überall eine _semantische_ Änderung
> gezielt vorgenommen: (a=b) --> (a=b,a)
> die dem Compiler den Grund zur Warnung wegnahm.


Und warum nicht das sehr viel leichter verstaendliche ((a=b)!=NULL) ???

> Die Folge dieser Änderung war ein Shitstorm - wie üblich:
> ---------------------------------------------------------
> o Ich hätte den Code _verkompliziert_


Stimmt.

> o um die Compiler-Analyse _auszutricksen_


Stimmt.

> o Meine Änderung sei überflüssig


Stimmt. Will man die Warnung vermeiden, waere der Vergleich mit 0 (bzw. im
Falle eines Pointers mit NULL, um anzuzeigen, dass man mit einer Nullpointer
constant vergleicht) die bessere Alternative.

> o "Aha, statt p=sp in eine sinnvolle Anweisung unzuwandeln
> suchst Du nach einer anderen unsinnigen Anweisung, die
> zufälligerweise keine Warnung verursacht."
> 'p=sp' ist also unsinnig.


An der zitierten Stelle wurde sp nicht veraendert. p wurde als Variable neu
eingefuehrt, obwohl die angesprochenenen Operationen auch gleich mit sp statt
mit dem neu dejkarierten und auf den Wert von sp initialisierten p haetten
gemacht werden koennen. "p" ist an der Stelle ueberfluessig (wie bereits
jemand korrekterweise anmerkte).

> '(p=sp,p)' ist ebenfalls unsinnig.


Ja. Wenn man den Wert der Zuweisung auf ungleich 0 testen moechte, waere
((p=sp)!=0) die empfehlenswerte Methode, weil man darin die eigentliche
Intention erheblich leichter erkennt als in deinem Vorschlag.

> '(p=sp,p)' löst _zufällig_ keine Warnung aus.


Die Chance, dass ein Compiler so etwas mit einer Warnung quittiert ist
hoeher als beim expliziten Vergleich.

> o "Und hast offenbar nicht kapiert, was ich mir schon als absoluter
> C Anfänger nach der ersten Beschreibung des ,-Ops im K&R 2ndEd
> hinter die Ohren tätowiert habe: beim ','-Operator ist _NICHTS_
> bzgl. der *Reihenfolge* der Auswertung definiert!"


Es wurde bereits korrigiert, dass der Komma-Operator einen Sequenzpunkt
darstellt und deswegen dieses Argument unzutreffend ist.

> Ich hingegen bin der Meinung, daß meine Änderung eine von mehreren
> in C gültigen Maßnahmen ist, um einer solchen Warnung den Grund
> zu nehmen. Meiner Meinung nach sogar die beste aller Möglichkeiten.


.... und die uebersichtlichste (weil direkte Umsetzung dessen, was du
eigentlich pruefen wolltest, naemlich den Wert der Zuordnung auf ungleich
0, bei weitem uebersichtler waere als dein Konstrukt).

Tschuess,
Juergen Ilse (juergen)
Helmut Schellong (04.01.2019, 21:31)
On 01/04/2019 19:15, Rainer Weikusat wrote:
> Helmut Schellong <rip> writes:
> Dem wuerde ich zustimmen.
> Allerdings halte ich es fuer besser, unsinnige Warnungen zu ignorieren,
> als um sie herumzuhacken insofern das moeglich ist: Muss man mit Leuten
> zusammenarbeiten, denen Compilerausgaben grundsaetzlich als hoehere
> Wahrheit gelten, bleibt einem nichts anderes uebrig, als manche gezielt
> zu unterbinden.


Ja, das mache ich gewöhnlich auch:
-Wno-dangling-else \
-Wno-logical-op-parentheses \
-Wno-char-subscripts \
-Wno-string-plus-int \
-Wno-bitwise-op-parentheses \
-Wno-parentheses \
-Wno-empty-body \
-Wno-invalid-source-encoding \
Das ist mein aktuelles Standard-Set.

Ich war allerdings vor Weihnachten gezwungen, einen ganz
alten Compiler für Testzwecke in Betrieb zu nehmen, weil
ein neuer 64bit-Compiler defekte Exe erzeugt (Windows).
Das war der Auslöser für alles dies.
Helmut Schellong (04.01.2019, 21:43)
On 01/04/2019 20:25, Juergen Ilse wrote:
> Hallo,
> Helmut Schellong <rip> wrote:
> Und warum nicht das sehr viel leichter verstaendliche ((a=b)!=NULL) ???


Ganz einfach:
o Es war an etwa 150 Stellen zu ändern.
o Ich finde meine Lösung (etwas) verständlicher und übersichtlicher.
o !=NULL hinzuzufügen ist aufwendiger als »,p«.
o Ich konnte bei meiner Lösung fast immer ein Klammerpaar eliminieren.
o Bei !=NULL muß man untersuchen, ob Pointer betroffen sind oder nicht.
o Ich verwende öfters den Komma-Operator, wie von D.Ritchie empfohlen.
Rainer Weikusat (04.01.2019, 23:11)
Juergen Ilse <news> writes:
> Helmut Schellong <rip> wrote:


[...]

>> Ausgangsbasis ist:
>> ,------------------------------------------------------
>> |if (mode==RV_ANMI && (p=sp) && p->vsp && !p->otyp &&
>> | p->ln==ln && !memcmp(p->name,name,ln)) return p;
>> '------------------------------------------------------
>> wo der Compiler (p=sp) anprangerte,


[...]

>> Ich hatte daraufhin überall eine _semantische_ Änderung
>> gezielt vorgenommen: (a=b) --> (a=b,a)
>> die dem Compiler den Grund zur Warnung wegnahm.


[...]

>> o um die Compiler-Analyse _auszutricksen_

> Stimmt.


Wie bereits geschrieben: Das sehe ich nicht so. Ein Ausdruck a = b
dessen Rueckgabewert benutzt wird, koennte auch ein verungluecktes a ==
b sein, bei a = b, a ist das eindeutig nicht der Fall.

[...]

> An der zitierten Stelle wurde sp nicht veraendert. p wurde als Variable neu
> eingefuehrt, obwohl die angesprochenenen Operationen auch gleich mit sp statt
> mit dem neu dejkarierten und auf den Wert von sp initialisierten p haetten
> gemacht werden koennen. "p" ist an der Stelle ueberfluessig (wie bereits
> jemand korrekterweise anmerkte).


Das haengt vom weiteren Code ab. ZB koennte p im Folgenden veraendert
werden, falls sp kein Nullzeiger war und der urspruengliche Wert noch
gebraucht. ZB um die Laenge der Sequenz [sp, p) zu berechnen.

>> '(p=sp,p)' ist ebenfalls unsinnig.

> Ja. Wenn man den Wert der Zuweisung auf ungleich 0 testen moechte, waere
> ((p=sp)!=0) die empfehlenswerte Methode, weil man darin die eigentliche
> Intention erheblich leichter erkennt als in deinem Vorschlag.


Das mag man so sehen, dann ist es aber unabhaengig vom konreten
Konstrukt. Andererseits ist die Idee, dass ein gueltiger Zeiger in einem
bool'schen Kontext als wahr und ein ungueltiger als falsch angesehen
wird, nicht eben weit hergeholt und man spart sich dadurch uU eine Menge
von Vergleichsoperatoren und -operanden, die inhaltich nichts zum Text
beitragen.
Juergen Ilse (05.01.2019, 01:04)
Hallo,

Helmut Schellong <rip> wrote:
> On 01/04/2019 20:25, Juergen Ilse wrote:
> Ganz einfach:
> o Es war an etwa 150 Stellen zu ändern.


.... und deine Aenderung reduzierte die Zahl der zu aendernden Stellen?
Wohl kaum ...

> o Ich finde meine Lösung (etwas) verständlicher und übersichtlicher.


Dafuer duerftest du nicht allzuviel Zustimmung bekommen ...

> o !=NULL hinzuzufügen ist aufwendiger als »,p«.


Erlaubt dein Editor keine Macros und/oder suchen/ersetzen mit regexp?

> o Ich konnte bei meiner Lösung fast immer ein Klammerpaar eliminieren.


Und welchen Vorteil bringt das?

> o Bei !=NULL muß man untersuchen, ob Pointer betroffen sind oder nicht.


Dann nimm !=0, das passt nicht nur fuer Pointer und geht mit beiden.

> o Ich verwende öfters den Komma-Operator, wie von D.Ritchie empfohlen.


"Wenn du ein Hammer bist, sieht jedes Problem wie ein Nagel aus ...".
Ich bin kein Hammer, und der Komma-Operator ist nicht das Allheilmittel,
sondern nur dort sinnvoll, wo er die gewuenschte Funktion klarer aus-
drueckt als andere Formulierungen. Letzteres ist IMHO im von dir gepostetzen
Fall eben nicht gegeben.

Tschuess,
Juergen Ilse (juergen)
Helmut Schellong (05.01.2019, 02:20)
On 01/05/2019 00:04, Juergen Ilse wrote:

>>> Und warum nicht das sehr viel leichter verstaendliche ((a=b)!=NULL) ???

>> Ganz einfach:
>> o Es war an etwa 150 Stellen zu ändern.

> ... und deine Aenderung reduzierte die Zahl der zu aendernden Stellen?
> Wohl kaum ...


Richtig, meine Änderung mußte ich an etwa 150 Stellen vornehmen.

>> o !=NULL hinzuzufügen ist aufwendiger als »,p«.

> Erlaubt dein Editor keine Macros und/oder suchen/ersetzen mit regexp?


Doch, aber 150 Stellen in 30 Dateien zu ändern, per s/.../.../,
wie soll das gehen, wenn jede Stelle anders ist?!
Ein RA dafür ist nicht formulierbar.
Ich mußte schon alle Stellen aufsuchen, zu denen es eine Warnung gab.
Beispiel: && (px=&sp[i],q=px->list, q) &&

>> o Ich konnte bei meiner Lösung fast immer ein Klammerpaar eliminieren.

> Und welchen Vorteil bringt das?


Es wird übersichtlicher.

>> o Bei !=NULL muß man untersuchen, ob Pointer betroffen sind oder nicht.

> Dann nimm !=0, das passt nicht nur fuer Pointer und geht mit beiden.


Aber die Pointer-Kennzeichnung 'NULL' fehlt dann.
Ich habe an 343 Stellen NULL in Verwendung.
Je nach Kontext.
Helmut Schellong (07.01.2019, 16:36)
On 01/04/2019 18:40, Helmut Schellong wrote:
> Gemeint sind Warnungen, die vor eventuellen Irrtümern warnen:
> daß anstelle einer Zuweisung (=) eine Gleichheitsprüfung (==)
> gemeint ist, oder daß die Operatorenränge von & | && ||
> verwechselt wurden. [...]


-Wno-dangling-else
-Wno-empty-body
-Wno-logical-op-parentheses
-Wno-bitwise-op-parentheses
-Wno-parentheses
-Wno-invalid-source-encoding

Letztlich sind solche Warnungen ein (kleines) Ärgernis.
Sie sind stets lästig, falls sie voreingestellt sind.

o Jeder Operator hat einen Rang.
o Folglich muß unweigerlich der Rang beachtet werden, sobald
Operatoren in einem Ausdruck geschrieben werden.
o Die Ränge existieren, damit _keine_ Klammern geschrieben
werden müssen.
o Diese Warnungen erzwingen überflüssige Klammern.
Genau das, was ja vermieden werden soll.
o Es gibt neben && und & noch weitere Operatoren (mit
Rang), bei denen ein Irrtum vorliegen könnte.
Für die es jedoch keine Warnung gibt.

Es wäre sinnvoller, am Ende einer Kompilierung eine
Aufmerksamkeit erregende Sammelnotiz auszugeben!
Die auch unterdrückbar sein muß.

Man soll doch ruhig mal 'else ;' formulieren, damit die
else-Zweige korrekt zugeordnet sind und ein Platzhalter
für später vorhanden ist (dangling-else).
Jedoch 'empty-body' warnt genau dabei.

Es ist bemerkbar, daß diese Welt des Zuschüttens
mit Warnungen doch reichlich bescheuert ist.

Man sollte einfach C richtig und vollständig können.

Wer bei:
!memcmp(dat.p, kz[k].p, l=kz[k].l)
^^^
fragt: "Ja, wie geht das denn?!", der kann C nicht richtig.

Man muß nämlich wissen, daß ein Trennzeichen (,) sich niemals
mit irgendeinem anderen Zeichen zusammenbindet.
Ebenso muß man wissen, daß das Komma hier als trennender
Punktuator wirkt (ohne Rang), und nicht als Komma-Operator.
Aber auch der Komma-Operator hat den niedrigsten Rang.
G.B. (09.01.2019, 00:40)
On 04.01.19 19:15, Rainer Weikusat wrote:

> Die Warnung soll auf moegliche
> Verwechslungen von == und = hinweisen. Fuer (a = b) ist dass gegeben,
> fuer (a = b, a) nicht, weil (a == b, a) keinen Sinn haette (es ist
> gleichwertig zu a).


Mit gewissen Einschränkungen gleichwertig, meine ich:

#include <stdio.h>

int main() {
int a, b;

a = b = 0;
puts((char*[]){"ja", "nein"}[a == b, a]);
a = b = 1;
puts((char*[]){"ja", "nein"}[a == b, a]);

a = b = 0;
puts((char*[]){"ja", "nein"}[a = b, a]);
a = b = 1;
puts((char*[]){"ja", "nein"}[a = b, a]);
}

Die Warnungen waren reichhaltig.
Rainer Weikusat (09.01.2019, 00:51)
"G.B." <bauhaus> writes:
[..]
> puts((char*[]){"ja", "nein"}[a = b, a]);
> }
> Die Warnungen waren reichhaltig.


Was soll das jetzt demonstrieren? Ein zusammengesetzer Ausdruck

a == b, a

berechnet und verwirft den Wert von a == b[*] und gibt den von a
zurueck.
[*] oder auch nicht: Der Wert wird nicht benutzt und Seiteneffekte gibt
es (ohne volatile) auch kein.
G.B. (09.01.2019, 09:06)
On 08.01.19 23:51, Rainer Weikusat wrote:
> "G.B." <bauhaus> writes:
> Was soll das jetzt demonstrieren?


Vermutlich nur, dass ich der pronominalen Struktur deiner
Behauptung einer Ursache etwas viel Verwechslungsmöglichkeit
abgewinnnen konnte. Ich vermute diese Deutung: weil nach als
allgemein angenommener Auffassung (a == b, a) kein Sinn zugeschrieben
werden dürfe, fällt "das Gegebene" für (a = b, a) weg. (Na ja,
ob aus dem Sinnlosen eine Ursache abgeleitet werden sollte...)
Es könne also eine mögliche Verwechslung, nach der Bewertung,
nicht geben, Bewertung durch den compiler, der warnt.
Warnungen sind freilich für Menschen gemacht, auch nicht
für compiler auf zwei Beinen, oder solche, die sich dafür
halten.

"Es" sind andererseits beide (...) gleichwertig zu a, an
einem Punkt, oder nicht?
Helmut Schellong (09.01.2019, 11:10)
On 01/09/2019 08:06, G.B. wrote:
> On 08.01.19 23:51, Rainer Weikusat wrote:
>> "G.B." <bauhaus> writes:


[..]
> Warnungen sind freilich für Menschen gemacht, auch nicht
> für compiler auf zwei Beinen, oder solche, die sich dafür
> halten.


Ich hatte bei der Veränderung des Ausdrucks
von (a=b) -> (a=b,a)
an die Compiler-Entwickler gedacht, die für ganz bestimmte
Ausdrücke Warnungen eingebaut haben, vielleicht weil MISRA
dort viele Fehler entdeckt hatte.

Und zwar wollte ich den Ausdruck so einfach wie möglich
verändern, unter Beibehaltung der Operation und des Resultates,
so daß der Compiler nicht mehr getriggert wird.

(a=b)!=0
beseitigt ja ebenfalls die Warnung, obwohl
(a==b)!=0
sinnvoll ist.

&& (a==b) &&
Die Klammern sind hier redundant, wegen des Operatorrangs.
Die Warnung ist also schon deshalb fragwürdig.

Andere Warnungen dieser Klasse lassen sich leider nicht
elegant beseitigen, sondern nur durch redundante Klammern,
die das machen, was der Rang der Operatoren bereits
gemacht hat.
Rainer Weikusat (09.01.2019, 19:09)
"G.B." <bauhaus> writes:
> On 08.01.19 23:51, Rainer Weikusat wrote:
> Vermutlich nur, dass ich der pronominalen Struktur deiner
> Behauptung einer Ursache etwas viel Verwechslungsmöglichkeit
> abgewinnnen konnte. Ich vermute diese Deutung: weil nach als
> allgemein angenommener Auffassung (a == b, a) kein Sinn zugeschrieben
> werden dürfe, fällt "das Gegebene" für (a = b, a) weg. (Na ja,
> ob aus dem Sinnlosen eine Ursache abgeleitet werden sollte...)


Die Motivation fuer die Warnung ist, dass eine Zuweisung, deren Ergebnis
verwendet wird, moeglicherweise ein Test auf Gleichheit haette werden
wollen, weil manche Leute

3 = 4

als Funktion mit einem bestimmten Rueckgabewert und nicht als unsinnige
Tatsachenbehauptung ansehen (besonders logisch ist das auch nicht).

Da es keinen technischen Grund gibt, einen Ausdruck

a == b, a

zu benutzen, faellt die Verwechslungsmoeglichkeit hier weg: Eventuell
wollte jemand unsinnigen Code schreiben, aber diese Annahme scheint mir
als Basis fuer eine Warnung recht schwach.

[...]

> "Es" sind andererseits beide (...) gleichwertig zu a, an
> einem Punkt, oder nicht?


Nein.

a == b, a

ist dasselbe wie a,

a = b, a

hat denselben Wert wie b und danach gilt a == b.
Ähnliche Themen