C++ kann Verzweifelung verursachen

Für allgemeine Fragen zur Programmierung, welche nicht! direkt mit Lazarus zu tun haben.

Re: C++ kann Verzweifelung verursachen

Beitragvon Mathias » 13. Jul 2017, 16:09 Re: C++ kann Verzweifelung verursachen

IAR Embedded Workbench

Ist dies ein Clone von Atmel-Studio ?


"int" ist ohnehin nicht "eindeutig", sondern Architektur- und damit Compiler-Abhängig.

Beim Integer würde ich mich mal bei Pascal verlassen, auch wen es jetzt bei FPC immer 32Bit ist.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 3056
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon Socke » 13. Jul 2017, 20:24 Re: C++ kann Verzweifelung verursachen

Mathias hat geschrieben:Beim Integer würde ich mich mal bei Pascal verlassen, auch wen es jetzt bei FPC immer 32Bit ist.

Integer ist kein Datentyp sonder nur ein Alias - entweder für ShortInt im Default-Modus oder für Longint im ObjFPC-/Delphi-Modus.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Socke
 
Beiträge: 2374
Registriert: 22. Jul 2008, 18:27
Wohnort: Köln
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 8.1/Debian GNU/Linux/Raspbian | 
CPU-Target: 32bit x86 armhf
Nach oben

Beitragvon siro » 13. Jul 2017, 21:19 Re: C++ kann Verzweifelung verursachen

Der IAR hat mit Atmel nichts zu tun.

Die haben eine komplett eigene IDE und sogar eigene C-Compiler für verschiedene Prozessoren.
Unsere Firma hat sich die "teure" IDE für die Arm Prozessoren gekauft.
IAR hat sich sogar ein Tüv Zertifikat geben lassen.

Das sollte man sich auch mal kurz angucken:
http://www.elektronikpraxis.vogel.de/so ... es/426198/

Habe mich ein Jahr lang mit dem System rumgeqält, bin dann umgestiegen auf die Freeware LPCxpresso von NXP
Diese funktioiniert im Prinzip genauso gut und ist bis 256KByte Code Freeware
LPCXpressor benutzt die Open Source GNU Compiler.
Durch die Freeware kann ich nun auch meine privatern Projekte damit programmieren.
Grüße von Siro
"C" verCehnfacht die Entwicklungszeit...
siro
 
Beiträge: 206
Registriert: 23. Aug 2016, 13:25
Wohnort: Berlin
OS, Lazarus, FPC: Windows 7 Windows 8.1 Windows 10 | 
CPU-Target: 64Bit
Nach oben

Beitragvon mschnell » 14. Jul 2017, 08:52 Re: C++ kann Verzweifelung verursachen

Elektronik Praxis hat geschrieben:char c1;
c1 = ~0x80;
if (c1 == ~0x80)
{ //wird nie erreicht}

Wieso beschweren die sich ?
"Char" ist genau wie "int" definitionsgemäß Compiler-abhängig. Bei manchen Compilern ist es signed, bei anderen unsigned. für die geplante Verwendung als druckbares Zeichen ist das in der Regel egal.

Wenn man mit 8 Bit großen Zahlen rechen will, sollte man (wie jeder C-Programmierer weis) "signed char" oder "unsigned char" verwenden, oder besser "uint8_t" oder "int8_t".

-Michael
mschnell
 
Beiträge: 3150
Registriert: 11. Sep 2006, 09:24
Wohnort: Krefeld
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ) | 
CPU-Target: X32 / X64 / ARMv5
Nach oben

Beitragvon Timm Thaler » 14. Jul 2017, 12:13 Re: C++ kann Verzweifelung verursachen

mschnell hat geschrieben:
Elektronik Praxis hat geschrieben:char c1;
c1 = ~0x80;
if (c1 == ~0x80)
{ //wird nie erreicht}

Wenn man mit 8 Bit großen Zahlen rechen will, sollte man (wie jeder C-Programmierer weis) "signed char" oder "unsigned char" verwenden, oder besser "uint8_t" oder "int8_t".


Hilft Dir hier nicht, das Problem ist ein Anderes. Der Char c1 wird vom Compiler auf 32bit erweitert.

~0x80 ist 0x7F in c1. Durch die Erweiterung wird das zu 0x0000007F. Verglichen wird es jetzt mit einer Konstante, ~0x00000080, die negiert wird zu 0xFFFFFF7F. Klar, dass das nicht gleich ist.

Über so Mist bin ich beim GCC für AVR auch schon gestolpert, weil der Compiler meinte meine 8bit-Variablen unbedingt auf 16bit aufblähen zu müssen. Da muss man dann erstmal rumcasten, um das gewünschte Format zu erzwingen.
Timm Thaler
 
Beiträge: 369
Registriert: 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.6 FPC3.0.0, Raspbian Jessie Laz1.6 FPC3.0.0 | 
CPU-Target: Raspberry Pi 3
Nach oben

Beitragvon mschnell » 14. Jul 2017, 12:30 Re: C++ kann Verzweifelung verursachen

Timm Thaler hat geschrieben:Der Char c1 wird vom Compiler auf 32bit erweitert


Ich vermute, Du meinst:

in der Operation "c1 == ~0x80" wird der Wert in C1 auf 32 erweitert.

Das ist natürlich korrekt (wenn wir Annehmen, dass es ein Compiler für ein 32 Bit System ist.

(Nur der Vollständigkeit halber, Vorzeichen spielen hier keine Rolle, aber da kann man ebenso verwirrende Beispiele konstruieren, da bei manchen Compilern "char" Vorzeichen-behaftet ist, bei anderen nicht.)

Es ist auch völlig logisch, da - wie bereits besprochen - unspezifizierte Integer Konstanten den Typ "int" haben, und "int" Compiler-abhängig definiert ist (bei 32 Bit Ziel-Architektur meist ein Vorzeichen-behafteter 32 Bit Wert.)

Bei unterschiedlichen Typen in einer Operation wird wenn nötig vorzeichenlos in Vorzeichen-behaftet und die kleinere Bit-Zahl auf die größere gewandelt.

Die erste Operation ist "~", die zweite Operation ist "==".

"c1 == ~0x80" wandelt also völlig logisch "0x80" in einen Vorzeichen-behafteten Wert mit entsprechend viele (z.B. 32) Bits und den Wert in C1 auf (z.B.) 32 Bit Integer, aber bei einem Compiler, bei dem char als unsigned definiert ist mit positivem Vorzeichen. (Das Ergebnis ist übrigens auch ein "int" !!!)

-Michael
mschnell
 
Beiträge: 3150
Registriert: 11. Sep 2006, 09:24
Wohnort: Krefeld
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ) | 
CPU-Target: X32 / X64 / ARMv5
Nach oben

Beitragvon Timm Thaler » 14. Jul 2017, 14:36 Re: C++ kann Verzweifelung verursachen

Ähm nein, Du übersiehst die Tilde.

Bei der Zuweisung wird erst 0x80 zu 0x7F bitweise invertiert. Das 0x7F = dez 127 landet dann korrekt in der 32bit-Variable als 0x0000007F.

Egal ob char signed oder unsigned ist, 0x7F ist immer dez 127 und positiv.

Beim Vergleich wird aber mit einer Konstante verglichen, bei der aus 0x00000080 bitweise negiert 0xFFFFFF7F, also dez -129 wurde.

Nun könnte man meinen, dieser Fall ist arg konstruiert. Bei Mikrocontrollern ist aber so eine bitweise Invertierung gar nicht ungewöhnlich, zum Beispiel wenn Du einen low-aktiven Port einliest, invertierst und dann auf einen bestimmten Zustand vergleichen willst. Wenn Dir dann der Compiler zu den 8 Portpins noch 8 weitere dazuerfindet...
Timm Thaler
 
Beiträge: 369
Registriert: 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.6 FPC3.0.0, Raspbian Jessie Laz1.6 FPC3.0.0 | 
CPU-Target: Raspberry Pi 3
Nach oben

Beitragvon Mathias » 14. Jul 2017, 15:52 Re: C++ kann Verzweifelung verursachen

Ich habe mal folgen Code bei meinem Arduino probiert, es kommt wie du sagst "false".
Die Grösse von c1 ist immmerhin 1.
Code: Alles auswählen
void loop() {
   char c1;
   c1 = ~0x80;
   if (c1 == ~0x80) {
      Serial.println("true");
   } else {
      Serial.println("false");
   }
   Serial.println(sizeof(c1));
}

Ich poste diesen Code im Arduino-Forum, mal gucken was die dazu sagen. :wink:

Komisch mache ich aber
Code: Alles auswählen
   c1 = ~80;
   if (c1 == ~80) {

dann kommt "true". :roll:
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 3056
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon Timm Thaler » 14. Jul 2017, 17:09 Re: C++ kann Verzweifelung verursachen

Mathias hat geschrieben:Komisch mache ich aber
Code: Alles auswählen
   c1 = ~80;
   if (c1 == ~80) {

dann kommt "true". :roll:


Nee, nicht komisch.

0x80 ist entweder dez 128 im unsigned byte (0..255) oder dez -128 im signed byte (-128..127). Wird invertiert zu 127.

Dez 80 (0x50) wird invertiert zu dez -81 (0xAF). Bei der Erweiterung schleift der Compiler diesmal das Vorzeichen mit, da das führende Bit gesetzt ist. Es wird zu 0xFFAF erweitert und mit 0xFFAF verglichen, passt.

Der Witz im obigen Beispiel ist ja, dass aus einer Zahl mit Vorzeichenbit eine Zahl ohne Vorzeichenbit wird, aber wenn man das mit 8bit macht kommt dabei halt eine andere Zahl raus als wenn man das mit 16 oder 32bit macht.
Timm Thaler
 
Beiträge: 369
Registriert: 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.6 FPC3.0.0, Raspbian Jessie Laz1.6 FPC3.0.0 | 
CPU-Target: Raspberry Pi 3
Nach oben

Beitragvon Mathias » 14. Jul 2017, 17:36 Re: C++ kann Verzweifelung verursachen

Jetzt blicke ich langsam durch, der dumme C-Compiler macht aus einem gewöhnlichen char ein Signed.
Und in der If-Abfrage, macht er ein Unsigned.

Beo folgenden Code kommt ein true.
Code: Alles auswählen
   char c1;
   c1 = ~0x80;
   if (c1 == char(~0x80)) {   // oder if (c1 == 127) {
      Serial.println("true");
   } else {
      Serial.println("false");
   }

Aber wen man es auf der Binär-ebene anguckt, ist c1 immer %10000000, somit müsste die If-Abfrage immer erfüllt sein. :wink:

Ausser eben, wie du sagst, wird der char bei der If-Abfrage in einen 16Bit-Wert umgewandelt.
Man müsste dies mal mit einem Debugger genauer angucken, was da für Assembler-Befehle raus kommen.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 3056
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon Mathias » 14. Jul 2017, 20:25 Re: C++ kann Verzweifelung verursachen

Im Arduino-Forum habe ich eine Antwort bekommen, die Konstante 0x80 implementiert C++ als Integer.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 3056
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon mschnell » 15. Jul 2017, 12:19 Re: C++ kann Verzweifelung verursachen

Mathias hat geschrieben:Jetzt blicke ich langsam durch, der dumme C-Compiler macht aus einem gewöhnlichen char ein Signed.
Und in der If-Abfrage, macht er ein Unsigned.

Nee.
Ob "char" (ohne Zusatz) signed oder unsigned ist, ist Compiler-abhängig (und immer mindestens 8 Bit groß), dann aber durchgängig. Integer Konstanten (ohne Zusatz) sind immer "int", und "int" ist (soweit ich weiß immer) signed (und ebenfalls immer mindestens 8 Bit groß, aber in der Regel mindestens so viele Bit wie für einen Pointer notwendig sind).

-Michael
mschnell
 
Beiträge: 3150
Registriert: 11. Sep 2006, 09:24
Wohnort: Krefeld
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ) | 
CPU-Target: X32 / X64 / ARMv5
Nach oben

Beitragvon mschnell » 15. Jul 2017, 12:21 Re: C++ kann Verzweifelung verursachen

Mathias hat geschrieben:Im Arduino-Forum habe ich eine Antwort bekommen, die Konstante 0x80 implementiert C++ als Integer.

In C ist jede Integer Konstante ohne Zusatz-Angabe "int".

-Michael
mschnell
 
Beiträge: 3150
Registriert: 11. Sep 2006, 09:24
Wohnort: Krefeld
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ) | 
CPU-Target: X32 / X64 / ARMv5
Nach oben

Beitragvon siro » 15. Jul 2017, 14:59 Re: C++ kann Verzweifelung verursachen

int ist nach meiner Erkenntnis immer mindestens 16 Bit groß
ob int signed oder unsigned ist, scheint nicht genormt zu sein.
Aber generell ist alles was nicht explizit gewandelt wird ein int, also auch die angegebenen Konstanten.
Grüße von Siro
"C" verCehnfacht die Entwicklungszeit...
siro
 
Beiträge: 206
Registriert: 23. Aug 2016, 13:25
Wohnort: Berlin
OS, Lazarus, FPC: Windows 7 Windows 8.1 Windows 10 | 
CPU-Target: 64Bit
Nach oben

• Themenende •
Vorherige

Zurück zu Programmierung



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast

porpoises-institution
accuracy-worried