Mikrocontroller: "Compiler-Optimizer-Fehler" finden?

On 08.03.2015 04:32, Sieghard Schicktanz wrote:
Hallo Wolfgang,

Du schriebst am 07 Mar 2015 13:19:00 -0300:

Manches sieht eher aus nach experimenteller Datenverarbeitung

Goil, den Spruch muss ich mir merken :)

Das ist nix besonderes, sondern das Ergebnis von Debugging.

Ja, man hat solange am Programm rumgebastelt, bis es irgendwie lief.
Warum weiß man nicht.

Dazu mal ein Zeit aus <http://www.ganssle.com/tem/tem278.html>

We could, for instance, begin with cleaning up our language by no longer
calling a bug "a bug" but by calling it an error. It is much more honest
because it squarely puts the blame where it belongs, viz., with the
programmer who made the error. The animistic metaphor of the bug that
maliciously sneaked in while the programmer was not looking is
intellectually dishonest as it is a disguise that the error is the
programmer's own creation. The nice thing of this simple change of
vocabulary is that it has such a profound effect. While, before, a
program with only one bug used to be "almost correct," afterwards a
program with an error is just "wrong." - E. W. Dijkstra

--
Reinhardt
 
On 08.03.2015 00:19, Wolfgang Allinger wrote:
On 07 Mar 15 at group /de/sci/electronics in article mdf47r$dml$2@dont-email.me
rbehm@hushmail.com> (Reinhardt Behm) wrote:

Manches sieht eher aus nach experimenteller Datenverarbeitung

Goil, den Spruch muss ich mir merken :)


Saludos (an alle Vernünftigen, Rest sh. sig)
Wolfgang
Das andere ist die span-abhebende Datenverarbeitung. Ich habe schon
Systeme mit Floppies gesehen, wo die oft benutzten Spuren durchsichtig
waren.
Aber das gehört schon wieder in Bereich Greisenelektronik.

--
Reinhardt
 
Hallo Christian,

Du schriebst am Sat, 07 Mar 2015 22:23:55 +0100:

Sieghard Schicktanz schrieb:

aber nur ein arithmetisches "gleich" ["=="], ein boolesches "gleich"
fehlt.)

Wofßr bräuchte man denn das? Statt "if (var == TRUE)" schreibt man "if
(var)" und statt "if (var == FALSE)" schreibt man "if (!var)".

Und was "schreibt man" fĂźr "res= var1 == var2;", wenn var1 und var2 keine
sicheren booleschen Werte sind, das Ergebnis aber einer sein soll?
Da bleibt dann nur so eine Hilfskonstruktion wie "res= !var1 == !var2;".
SchÜn und einsichtig ist anders. Und das ist nur einer der mÜglichen Fälle.

--
--
(Weitergabe von Adressdaten, Telefonnummern u.ä. ohne Zustimmung
nicht gestattet, ebenso Zusendung von Werbung oder ähnlichem)
-----------------------------------------------------------
Mit freundlichen Grüßen, S. Schicktanz
-----------------------------------------------------------
 
Hallo Stefan,

Du schriebst am Sat, 07 Mar 2015 22:12:05 +0100:

(Außerdem kennt C doch sowieso keine richtigen boolschen Variablen..)

Seit ca. 16 Jahren hat C einen Datentyp "_Bool", der mithilfe des
Headerfiles <stdbool.h> auch unter seinem Ăźblichen Namen "bool" zur
VerfĂźgung steht.

Achnee, wirklich? _Das_ soll ein boolescher Datentyp sein? Das ist doch
auch bloß wieder ein integer-Typ in (nicht mehr ganz) neuer Verkleidung.
Halt nur mit einem Wertebereich von (0, 1), etwa wie ein ("unsigned"!)
1-Bit-Bitfeld.

#include <stdio.h>
#include <stdbool.h>

int main (int argc, char * argv [])
{
bool b, c;
int i, k;

b= !c;
printf ("b: %d, c. %d\n", b, c);
i= b; k= c;
printf ("i: %d, k. %d\n", i, k);
b= ~k; c= ~i;
printf ("b: %d, c. %d\n", b, c);
b += 1; c -= 1;
printf ("b: %d, c. %d\n", b, c);
return 0;
}

Das läßt sich problemlos compilieren, ohne daß der Compiler über
irgendwelche Typenprobleme mosert, es wird ohne Fehlermeldung abgearbeitet
und es liefert folgende Ausgabe:

b: 1, c. 0
i: 1, k. 0
b: 1, c. 1
b: 1, c. 0

--
--
(Weitergabe von Adressdaten, Telefonnummern u.ä. ohne Zustimmung
nicht gestattet, ebenso Zusendung von Werbung oder ähnlichem)
-----------------------------------------------------------
Mit freundlichen Grüßen, S. Schicktanz
-----------------------------------------------------------
 
On 08 Mar 15 at group /de/sci/electronics in article mdg5tm$rg7$1@dont-email.me
<rbehm@hushmail.com> (Reinhardt Behm) wrote:

On 08.03.2015 00:19, Wolfgang Allinger wrote:
On 07 Mar 15 at group /de/sci/electronics in article
mdf47r$dml$2@dont-email.me <rbehm@hushmail.com> (Reinhardt Behm)
wrote:

Manches sieht eher aus nach experimenteller Datenverarbeitung

Goil, den Spruch muss ich mir merken :)


Das andere ist die span-abhebende Datenverarbeitung. Ich habe schon
Systeme mit Floppies gesehen, wo die oft benutzten Spuren durchsichtig
waren.

Spanabhebende Datenverarbeitung war lange vor Floppy. zB. DEC RK02...

Da gabs echte Späne oder schon früher (Bryand (?) Autolift) danach SAGEM
Festkopfplatten mit ab und zu losen Köpfen :) Tolle Geräusche, man
wusste sofort: Du brauchst Dich nicht mehr zu beeilen :)

Später wurde die Technik von IBM mit den Winchester Platten wieder
reanimiert und verfeinert. Wenn die Schmierschicht durch Fliehkräfte
nach aussen wanderte oder gar die Oberfläche endgültig verlies: entweder
Späne bei der Landung oder abgerissenen Köppe bei Schlammpflügen...

Die Floppy war eher Schlapp-Datenverarbeitung :)

>Aber das gehört schon wieder in Bereich Greisenelektronik.

Jau, aber ruft Erinnerungen zurück an die 1. Festkopfplatte von SAGEM
die mir unterkam. Mit immerhin 128 Köpfen = Spuren zu je 1k Worte
(12bit, zusammen 128kWorte). Deutlich schneller als Lochstreifen :) Der
AEG60-10 Rechner dazu hatte 32kW Kernspeicher. IIRC 11uS Zykluszeit. Die
SAGEM hatte etwa die Grösse einer Waschmaschine nur mit mehr Problemen:

Die 1. wurde auf der Seite liegend auf einer Palette aus Fronkroich
angeliefert. Die hab ich erst garnicht abladen lassen.

Die 2. wurde dann beim Abladen aus etwa 30cm Höhe unsanft abgesetzt.
Franzose als Fahrer eben. Hauptsache die Golouise(?) fiel nicht runter
aus dem Mundwinkel. Test: auch tot, mindestens 32 Köpfe abgerissen.

Die 3. wurde dann von einem AEG-Ing im VW-Bus aus F geholt und war dann
brauchbar :) jedenfalls für ungefähr 4-6 Wochen.

Nein nein, das Projekt war nach Ansicht der Franzmänner eh nicht
zeitkritisch, da sowieso schon 6 Monate zu spät :(


Schönen Sonntag :)



Saludos (an alle Vernünftigen, Rest sh. sig)
Wolfgang

--
Wolfgang Allinger, anerkannter Trollallergiker :) reply Adresse gesetzt!
Ich diskutiere zukünftig weniger mit Idioten, denn sie ziehen mich auf
ihr Niveau herunter und schlagen mich dort mit ihrer Erfahrung! :p
(lt. alter usenet Weisheit) iPod, iPhone, iPad, iTunes, iRak, iDiot
 
Am 08.03.2015 um 00:47 schrieb Sieghard Schicktanz:

> Und was "schreibt man" fĂźr "res= var1 == var2;", wenn var1 und var2 keine

Ein EX-NOR ist als einzelner Operator nicht enthalten, es ist auch kein
boolesches xor vorhanden. Workaround ist die normierung auf boolsche
Werte und Nutzung des bitweisen Exklusiv-Oder, wobei die Symmetrie des
xor bzgl true/false ausgenutzt wird:

res = !(!var1 ^ !var2);

Sinnvollerweise verpackt man das der besseren Lesbarkeit aber in ein Makro:

#define bXOR(a,b) (!a ^ !b)
#define bXNOR(a,b) (!(!a ^!b))

Bernd
 
On 08.03.2015 16:49, Wolfgang Allinger wrote:
On 08 Mar 15 at group /de/sci/electronics in article mdg5tm$rg7$1@dont-email.me
rbehm@hushmail.com> (Reinhardt Behm) wrote:

On 08.03.2015 00:19, Wolfgang Allinger wrote:
On 07 Mar 15 at group /de/sci/electronics in article
mdf47r$dml$2@dont-email.me <rbehm@hushmail.com> (Reinhardt Behm)
wrote:

Manches sieht eher aus nach experimenteller Datenverarbeitung

Goil, den Spruch muss ich mir merken :)


Das andere ist die span-abhebende Datenverarbeitung. Ich habe schon
Systeme mit Floppies gesehen, wo die oft benutzten Spuren durchsichtig
waren.

Spanabhebende Datenverarbeitung war lange vor Floppy. zB. DEC RK02...

Da gabs echte Späne oder schon früher (Bryand (?) Autolift) danach SAGEM
Festkopfplatten mit ab und zu losen Köpfen :) Tolle Geräusche, man
wusste sofort: Du brauchst Dich nicht mehr zu beeilen :)

Ich hab's zwar nicht selbst erlebt, aber damals die Trümmer gesehen, wo
Teile einer IBM-Platte aus dem geschlossenen Gehäuse geflogen waren.

Später wurde die Technik von IBM mit den Winchester Platten wieder
reanimiert und verfeinert. Wenn die Schmierschicht durch Fliehkräfte
nach aussen wanderte oder gar die Oberfläche endgültig verlies: entweder
Späne bei der Landung oder abgerissenen Köppe bei Schlammpflügen...

Die Floppy war eher Schlapp-Datenverarbeitung :)

Aber das gehört schon wieder in Bereich Greisenelektronik.

Jau, aber ruft Erinnerungen zurück an die 1. Festkopfplatte von SAGEM
die mir unterkam. Mit immerhin 128 Köpfen = Spuren zu je 1k Worte
(12bit, zusammen 128kWorte). Deutlich schneller als Lochstreifen :) Der
AEG60-10 Rechner dazu hatte 32kW Kernspeicher. IIRC 11uS Zykluszeit. Die
SAGEM hatte etwa die Grösse einer Waschmaschine nur mit mehr Problemen:

Die 1. wurde auf der Seite liegend auf einer Palette aus Fronkroich
angeliefert. Die hab ich erst garnicht abladen lassen.

Die 2. wurde dann beim Abladen aus etwa 30cm Höhe unsanft abgesetzt.
Franzose als Fahrer eben. Hauptsache die Golouise(?) fiel nicht runter
aus dem Mundwinkel. Test: auch tot, mindestens 32 Köpfe abgerissen.

Die 3. wurde dann von einem AEG-Ing im VW-Bus aus F geholt und war dann
brauchbar :) jedenfalls für ungefähr 4-6 Wochen.

Nein nein, das Projekt war nach Ansicht der Franzmänner eh nicht
zeitkritisch, da sowieso schon 6 Monate zu spät :(


Schönen Sonntag :)

Dir auch, meiner ist ja schon fast rum.


--
Reinhardt
 
Bernd Laengerich <bernd.laengerich@web.de> schrieb:
Am 08.03.2015 um 00:47 schrieb Sieghard Schicktanz:

Und was "schreibt man" fĂźr "res= var1 == var2;", wenn var1 und var2 keine

Ein EX-NOR ist als einzelner Operator nicht enthalten, es ist auch kein
boolesches xor vorhanden. Workaround ist die normierung auf boolsche
Werte und Nutzung des bitweisen Exklusiv-Oder, wobei die Symmetrie des
xor bzgl true/false ausgenutzt wird:

res = !(!var1 ^ !var2);

Sinnvollerweise verpackt man das der besseren Lesbarkeit aber in ein Makro:

#define bXOR(a,b) (!a ^ !b)
#define bXNOR(a,b) (!(!a ^!b))

Schäm dich, nicht so mit Klammern sparen.

#define bXOR(a,b) (!(a) ^ !(b))
#define bXNOR(a,b) (!(!(a) ^ !(b)))

Ansonsten gibt es Probleme, wenn du tatsächlich mal Ausdrßcke ßbergibst,
denn das "!" bindet ja doch verdammt stark.

Ralf
--
"ceterum censeo systemd esse delendam"

Ralf Döblitz * Schapenstraße 6 * 38104 Braunschweig * Germany
Mit UTF-8 kann man gleichzeitig äöüßÄÖÜæœłø‱¼½¾¤¹²³¢€£¥¶§¬÷×±©®™¡¿ verwenden …
 
Sieghard Schicktanz wrote:
Du schriebst am Sat, 07 Mar 2015 22:12:05 +0100:
(Außerdem kennt C doch sowieso keine richtigen boolschen Variablen.)

Seit ca. 16 Jahren hat C einen Datentyp "_Bool", der mithilfe des
Headerfiles <stdbool.h> auch unter seinem Ăźblichen Namen "bool" zur
VerfĂźgung steht.

Achnee, wirklich? _Das_ soll ein boolescher Datentyp sein? Das ist doch
auch bloß wieder ein integer-Typ in (nicht mehr ganz) neuer Verkleidung.
Halt nur mit einem Wertebereich von (0, 1), etwa wie ein ("unsigned"!)
1-Bit-Bitfeld.

Was ist daran kein boolescher Datentyp?

Wir reden von C, und C hat keine Hemmungen, irgendwas, was irgendwie
sinnvoll ineinander konvertierbar ist, auch einfach mal eben zu
konvertieren. C konvertiert auch enum und int nach float und andersrum
automatisch. bool ist da keine Ausnahme.

#include <stdio.h
#include <stdbool.h

int main (int argc, char * argv [])
{
bool b, c;
int i, k;

b= !c;

Das ist undefiniertes Verhalten, da c nicht initialisiert ist. Eine
uninitialisierte bool-Variable kann auch einen Wert haben, der weder
true noch false ist.

Aber das ist keine Besonderheit von C. Das kann z.B. in Pascal auch
passieren.


Stefan
 
Hallo Stefan,

Du schriebst am Sun, 08 Mar 2015 19:15:26 +0100:

Headerfiles <stdbool.h> auch unter seinem Ăźblichen Namen "bool" zur
....
Was ist daran kein boolescher Datentyp?

Er ist _nicht_ _in_kompatibel zu arithmetischen Typen.

Wir reden von C, und C hat keine Hemmungen, irgendwas, was irgendwie
sinnvoll ineinander konvertierbar ist, auch einfach mal eben zu

Nicht nur was sinnvoll konvertierbar ist, C konvertiert recht wild alles,
was _darstellungsmäßig_ konvertierbar ist, ungeachtet des Zwecks.

konvertieren. C konvertiert auch enum und int nach float und andersrum
automatisch. bool ist da keine Ausnahme.

Eben. Wobei die Konversion zwischen int und float sogar noch eine Änderung
der _Darstellung_ beinhaltet. Wird bei Konversion zwischen enum und int
lediglich die interne Darstellung anders interpretiert, ist das bei int
versus float nicht der Fall - das _ist_ eine Ausnahme.

#include <stdio.h
#include <stdbool.h

int main (int argc, char * argv [])
{
bool b, c;
int i, k;

b= !c;

Das ist undefiniertes Verhalten, da c nicht initialisiert ist. Eine

Hier war b "zufällig" anfangs 0, der gcc hat offenbar großzügig die
Deklarationen global angelegt. Ja, das ist ein Fehler im Programm.
Nur ändert dessen Korrektur nichts am Ergebnis und nichts an der Funktion.

uninitialisierte bool-Variable kann auch einen Wert haben, der weder
true noch false ist.

Aber das ist keine Besonderheit von C. Das kann z.B. in Pascal auch
passieren.

Nein. In Pascal - in _korrekt_ implementiertem Pascal - kann das _nicht_
passieren. Nein, in der Hinsicht ist FPC _nicht_ korrekt implementiert
(auch Delphi nicht). Beides sind inzwischen mehr C-Bastarde als Pascal-
Implementierungen.

--
--
(Weitergabe von Adressdaten, Telefonnummern u.ä. ohne Zustimmung
nicht gestattet, ebenso Zusendung von Werbung oder ähnlichem)
-----------------------------------------------------------
Mit freundlichen Grüßen, S. Schicktanz
-----------------------------------------------------------
 
Hallo Bernd,

Du schriebst am Sun, 08 Mar 2015 12:32:45 +0100:

Und was "schreibt man" fĂźr "res= var1 == var2;", wenn var1 und var2
....
Ein EX-NOR ist als einzelner Operator nicht enthalten, es ist auch kein
boolesches xor vorhanden. Workaround ist die normierung auf boolsche

Eben. (Wobei die Bezeichnung "EX-NOR" ein Euphemismus fĂźr "gleich" ist..)
Der Operator-Satz ist hier unvollständig, und der Programmierer muß
aufpassen, daß er immer die Löcher in der Sprachdefinition durch passende
Hilfskonstruktionen ĂźberbrĂźckt.

Werte und Nutzung des bitweisen Exklusiv-Oder, wobei die Symmetrie des
xor bzgl true/false ausgenutzt wird:

res = !(!var1 ^ !var2);

Das nutzt hier bloß garnichts, weil es eine genauso verquere Krücke
darstellt wie beim direkten Vergleichsoperator, es wird bloß noch eine
zusätzliche Invertierung gebraucht, die noch eine zusätzliche
FehlermĂśglichkeit mehr bietet ("!" vs. "~").

Sinnvollerweise verpackt man das der besseren Lesbarkeit aber in ein
Makro:

#define bXOR(a,b) (!a ^ !b)
#define bXNOR(a,b) (!(!a ^!b))

Jaja, solche MakroverschlĂźsselungen sind ein recht wesentlicher Bestandteil
der C-Codierung - je mehr Makros zur "besseren Lesbarkeit" eingesetzt
werden, desto schlechter verständlich wird der Code...
Experten verstecken die Makro-Definitionen dann auch noch in viele Ebenen
tief geschachtelten Header-Files in Unter- oder gar externen Verzeichnissen.

--
--
(Weitergabe von Adressdaten, Telefonnummern u.ä. ohne Zustimmung
nicht gestattet, ebenso Zusendung von Werbung oder ähnlichem)
-----------------------------------------------------------
Mit freundlichen Grüßen, S. Schicktanz
-----------------------------------------------------------
 
Hallo Ralf,

Du schriebst am Sat, 7 Mar 2015 22:07:30 +0000 (UTC):

Was im wesentlichen zeigt, daß C ein boolescher Vergleichsoperator
fehlt.

NĂś, der ist nur nicht so offensichtlich.
....
Du mußt halt auf logische Werte normalisieren:
!a == !b

Genau, Du mußt der Programmiersprache eine Krücke zur Hand geben, damit sie
Dich nicht auf die Schnauze knallen läßt. Und pass` bloß auf, daß Du das
_nie_ vergißt!

--
--
(Weitergabe von Adressdaten, Telefonnummern u.ä. ohne Zustimmung
nicht gestattet, ebenso Zusendung von Werbung oder ähnlichem)
-----------------------------------------------------------
Mit freundlichen Grüßen, S. Schicktanz
-----------------------------------------------------------
 
Hallo Reinhardt,

Du schriebst am Sun, 08 Mar 2015 08:38:56 +0800:

On 08.03.2015 04:32, Sieghard Schicktanz wrote:
Hallo Wolfgang,

Du schriebst am 07 Mar 2015 13:19:00 -0300:

Manches sieht eher aus nach experimenteller Datenverarbeitung

Goil, den Spruch muss ich mir merken :)

Das ist nix besonderes, sondern das Ergebnis von Debugging.

Ja, man hat solange am Programm rumgebastelt, bis es irgendwie lief.
Warum weiß man nicht.

Das ist inzwischen doch ein vielgepriesenes Standardverfahren, das sog.
"agile programming"...

> Dazu mal ein Zeit aus <http://www.ganssle.com/tem/tem278.html>
^^^^? Zitat?
....
> program with an error is just "wrong." - E. W. Dijkstra

Ja, damals (muß schon über ein Vierteljahrhundert her sein) hat man sowas
noch aussprechen dĂźrfen. Heute ist der Fehler doch eher die Wurzel fĂźr neue
"Funktionalitäten"... (was fßr ein Wortungetßm...)

--
--
(Weitergabe von Adressdaten, Telefonnummern u.ä. ohne Zustimmung
nicht gestattet, ebenso Zusendung von Werbung oder ähnlichem)
-----------------------------------------------------------
Mit freundlichen Grüßen, S. Schicktanz
-----------------------------------------------------------
 
Am 08.03.2015 um 21:06 schrieb Sieghard Schicktanz:

> Eben. (Wobei die Bezeichnung "EX-NOR" ein Euphemismus fĂźr "gleich" ist.)

Das ist das gleiche bei boolschen Datentypen. Allerdings ist der
praktische Einsatz davon in Programmen nahezu null, wenn ich auf meine
bisherige Karriere zurĂźckblicke.
In der CD4000-Reihe gibt es kein "Gleichheitsgatter", sehr wohl aber
XNOR, z.B. CD4077.

> Der Operator-Satz ist hier unvollständig, und der Programmierer muß

Der Operatorsatz ist immer unvollständig, den meisten Grundsprachen
fehlen einfache Operatoren fßr die nächste Primzahl,
Fouriertransformationen oder jeweils der übernächste Dienstag außer in
Monaten mit "R". Genausowenig findet man das
SN74-"tu-was-ich-will-Gatter" im Standardproduktkatalog von TI. Wenn man
in der Programmiersprache "LĂśten" arbeitet, sind die Fallstricke ebenso
vielfältig.

Bernd
 
On 09.03.2015 04:13, Sieghard Schicktanz wrote:
Hallo Reinhardt,

Du schriebst am Sun, 08 Mar 2015 08:38:56 +0800:

On 08.03.2015 04:32, Sieghard Schicktanz wrote:
Hallo Wolfgang,

Du schriebst am 07 Mar 2015 13:19:00 -0300:

Manches sieht eher aus nach experimenteller Datenverarbeitung

Goil, den Spruch muss ich mir merken :)

Das ist nix besonderes, sondern das Ergebnis von Debugging.

Ja, man hat solange am Programm rumgebastelt, bis es irgendwie lief.
Warum weiß man nicht.

Das ist inzwischen doch ein vielgepriesenes Standardverfahren, das sog.
"agile programming"...

Dazu mal ein Zeit aus <http://www.ganssle.com/tem/tem278.html
^^^^? Zitat?
ups.
BTW: Jack Ganssle's Newletter ist sehr empfehlenswert.
....
program with an error is just "wrong." - E. W. Dijkstra

Ja, damals (muß schon über ein Vierteljahrhundert her sein) hat man sowas
noch aussprechen dĂźrfen. Heute ist der Fehler doch eher die Wurzel fĂźr neue
"Funktionalitäten"... (was fßr ein Wortungetßm...)
Zum GlĂźck nicht Ăźberall. Wenn ich so bei meinen Entwicklungen arbeiten
wĂźrde, dann fiele der Flieger vom Himmel - und kĂśnnte mich treffen.

--
Reinhardt
 
On 09.03.2015 21:33, Edzard Egberts wrote:
Heinz Saathoff wrote:
Edzard Egberts schrieb:

Sieghard Schicktanz wrote:
#include <stdio.h
#include <stdbool.h

int main (int argc, char * argv [])
{
bool b, c;
int i, k;

b= !c;

Das ist undefiniertes Verhalten, da c nicht initialisiert ist. Eine

Hier war b "zufällig" anfangs 0

Das ist aber ein großer Zufall, nämlich 1:254. bool wird intern ja
meistens in ein Byte gepackt, nicht in ein Bit und der Operator '!' ist
bei bool meistens als bitweise Invertierung der gesamten Variablen
implementiert.

Was der Compiler für eine bool-Variable nimmt ist
_implementation_defined_. Es wird oft sogar die effektivste Größe
genommen, das können auf einem 64-bit System auch 8 Byte sein.
Irgendwelchen Annahmen darüber sind spätestens beim Wechsel des
Conmpilers oder auch nur beim Wechsel von 16 zu 32 oder zu 64 Bit Modus
hinfällig.

Welcher Compiler macht denn sowas? Das ist ja eine fehlerhafe
Umsetzung des Operators !

Das wäre ein fehlerhafter Compiler. Auch das Resultat des Operators !
ist im Standard als 0 oder 1 definert. Wenn bei Deinem Compiler alle
Bits umgedreht werden, verwechselt der ! mit ~.
Bei dem Effekt bin ich mir sicher, bei meiner Erklärung nicht so. Kann
auch sein, dass der ! nur das Bit Null invertiert (halte ich sogar für
wahrscheinlicher als meine vorhergehende "komplett invertieren" Deutung,
weil das mit den Werten 0 / 1 besser hinkommt) und die Abfrage dann
wegen der anderen Bits durcheinander kommmt.

Wenn er nur das letzte Bit umdreht, ist er fehlerhaft. Und das ist kein
Bug, sondern ein _Fehler_, um Edsger Dykstra zu zitieren.

Was würdest Du hier erwarten:

Ein Beispiel mit nicht initialisierten Bool-Werten.

bool a, b;
while (a!= b)
{
cout << "a!= b" << endl;
a= !a;
}

Nach dem ersten Durchlauf durch die Schleife hat a den Wert 0 oder 1,
abhängig davon was zufällig vorher drin stand. Danach wechselt es
zwischen 0 und 1, unabhängig davon was jemals vorher drin stand. Wenn b
nicht zufällig 0 oder 1 war, läuft das ganze dann endlos.
Wenn's nicht so ist, schmeiß den Compiler weg.

Wer mit nicht initialisierten Werten arbeitet und sinnvoles Verhalten
erwartet, sollte besser die Finger von der Tastatur lassen. Bei sowas
sollten bei einem Code-Review die Alarmglocken angehen.

Gescheiterweise macht man die Initialisierung schon in der Deklaration.
Wenn man danach nicht wild die Datentypen vermanscht, gibt es auch keine
seltsamen Überraschungen.
Zuweisungen von nicht boolschen Werten (also anderes als 0 oder 1) ist
ganz einfach _undefined_behaviour_.

--
Reinhardt
 
Sieghard Schicktanz wrote:
Du schriebst am Sun, 08 Mar 2015 19:15:26 +0100:
Headerfiles <stdbool.h> auch unter seinem Ăźblichen Namen "bool" zur
...
Was ist daran kein boolescher Datentyp?

Er ist _nicht_ _in_kompatibel zu arithmetischen Typen.

Das liegt aber nicht an bool, sondern - wie ich schon schrieb - daran,
dass in C jeder Typ jedermanns Freund ist.

Wir reden von C, und C hat keine Hemmungen, irgendwas, was irgendwie
sinnvoll ineinander konvertierbar ist, auch einfach mal eben zu

Nicht nur was sinnvoll konvertierbar ist, C konvertiert recht wild alles,
was _darstellungsmäßig_ konvertierbar ist, ungeachtet des Zwecks.

Nein, eben gerade nicht. C konvertiert Werte. Exemplarisch: ISO
9899:1999 §6.3.1.3p2: "Otherwise, if the new type is unsigned, the value
is converted by repeatedly adding or subtracting one more than the
maximum value that can be represented in the new type until the value is
in the range of the new type", womit aus dem 'signed int' -1 mit der
Repräsentation 0x8001 (...sign/magnitude-Darstellung vorausgesetzt) der
'unsigned int' mit der Repräsentation '0xFFFF' werden kann.

konvertieren. C konvertiert auch enum und int nach float und andersrum
automatisch. bool ist da keine Ausnahme.

Eben. Wobei die Konversion zwischen int und float sogar noch eine Änderung
der _Darstellung_ beinhaltet. Wird bei Konversion zwischen enum und int
lediglich die interne Darstellung anders interpretiert, ist das bei int
versus float nicht der Fall - das _ist_ eine Ausnahme.

Nein, das ist der Regelfall. Um Repräsentationen zu konvertieren,
schrammt man gerne mal am undefinierten Verhalten vorbei,
int i = *(int*) &floatVar;
ist z.B. nicht zulässig (§6.5p7).

)
{
bool b, c;
int i, k;

b= !c;

Das ist undefiniertes Verhalten, da c nicht initialisiert ist. Eine

Hier war b "zufällig" anfangs 0, der gcc hat offenbar großzügig die
Deklarationen global angelegt.

Nein, gcc hat zufällig eine Speicherzelle oder ein Register mit dem Wert
0 erwischt.

uninitialisierte bool-Variable kann auch einen Wert haben, der weder
true noch false ist.

Aber das ist keine Besonderheit von C. Das kann z.B. in Pascal auch
passieren.

Nein. In Pascal - in _korrekt_ implementiertem Pascal - kann das _nicht_
passieren. Nein, in der Hinsicht ist FPC _nicht_ korrekt implementiert
(auch Delphi nicht). Beides sind inzwischen mehr C-Bastarde als Pascal-
Implementierungen.

In Pascal haben uninitialisierte lokale Variablen genauso wie in C
undefiniertes Verhalten.

ISO 10206:1990 6.4.2.1: "The initial state denoted by an enumerated-type
or a subrange-type shall be totally-undefined." (boolean ist ein
Enumerationstyp.)


Stefan
 
Sieghard Schicktanz wrote:
#include <stdio.h
#include <stdbool.h

int main (int argc, char * argv [])
{
bool b, c;
int i, k;

b= !c;

Das ist undefiniertes Verhalten, da c nicht initialisiert ist. Eine

Hier war b "zufällig" anfangs 0

Das ist aber ein großer Zufall, nämlich 1:254. bool wird intern ja
meistens in ein Byte gepackt, nicht in ein Bit und der Operator '!' ist
bei bool meistens als bitweise Invertierung der gesamten Variablen
implementiert. So lange c also nicht zufällig als Null oder 255
initialisiert ist, ergibt "c= !c" immer true (> 0). Als Beispiel sei C=
0x0f, invertiert gibt das 0xf0 und beide Werte sind immer > 0. bool
nicht zu initialsieren ist eine bĂśse Falle, die man unbedingt vermeiden
sollte.
 
Michael Schwingen schrieb:

On 2015-03-07, Stefan Reuther <stefan.news@arcor.de> wrote:
var = expr > 0;
:
if (var == TRUE) ...

Das heißt ja auch 'if (var)'.

aber nur, wenn expr unsigned ist.

Warum das? In C ist doch
if (var)
äquivalent zu
if(var != 0)
und damit sowohl für signed als auch unsigned variable gültig. Sogar
für float/double ist das so.


- Heinz
 
Edzard Egberts schrieb:

Sieghard Schicktanz wrote:
#include <stdio.h
#include <stdbool.h

int main (int argc, char * argv [])
{
bool b, c;
int i, k;

b= !c;

Das ist undefiniertes Verhalten, da c nicht initialisiert ist. Eine

Hier war b "zufällig" anfangs 0

Das ist aber ein großer Zufall, nämlich 1:254. bool wird intern ja
meistens in ein Byte gepackt, nicht in ein Bit und der Operator '!' ist
bei bool meistens als bitweise Invertierung der gesamten Variablen
implementiert.

Welcher Compiler macht denn sowas? Das ist ja eine fehlerhafe
Umsetzung des Operators !
Was würdest Du hier erwarten:
int i;
for(i=0; i<256; ++i) {
printf("%d\n", !i);
}
Alles andere als 1 0 0 0 ...
wäre falsch.
 

Welcome to EDABoard.com

Sponsor

Back
Top