C++ kann Verzweifelung verursachen
-
- Beiträge: 1445
- Registriert: Fr 10. Okt 2008, 23:54
- OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
- CPU-Target: 32/64Bit
Re: C++ kann Verzweifelung verursachen
Wenn man mit einem C Compiler auf einem µC arbeitet dann ist die Datenbreite einer int Variable abhängig vom µC.
Bei einem AVR (Arduino) ist das 16 Bit, bei einem STM32 32 Bit.
Für jemanden der wenig/keine Ahnung von µC hat sehen diese Effekte verwirrend und buggy aus, jedoch ist das so im C Compiler hinterlegt. (so auch bei 32 / 64 Bit Programmen im PC!)
Die einzige Abhilfe ist die Datei
#include <stdint.h>
mit ein zu binden. Diese Datei definiert Integer Datentypen so, dass die auch genau das Format haben wie man will.
int8_t
int16_t
int32_t
int64_t
uint8_t
uint16_t
uint32_t
uint64_t
Und das ganze funktioniert garantiert, auch wenn man den Quellcode man von einem AVR >> STM32 µC portieren sollte, falls man doch mal feststellen sollte dass der AVR eine olle Krücke, die schon steinalt ist.
Merke: NIEMALS den Datenty int im µC UND PC verwenden!
Das Verhalten vom C Compiler ist schon so, seit dem es den ersten C Compiler gab.
Konstante:
1000 >> irgend ein int typ, der Compiler muss selbst was erfinden
1000L >> eine Konstante vom Typ "long"
1000UL >> eine Konstante vom Typ "unsigned long"
Um heraus zu finden wie viele bytes ein Datentyp belegt kann man das abfragen:
SizeOfDatentyp = sizeof(int); // beim AVR > 2 Byte, beim STM32 > 4 Byte
SizeOfDatentyp = sizeof(long); // beim AVR > 4 Byte, beim STM32 > 4 Byte
SizeOfDatentyp = sizeof(long long);
Bei einem AVR (Arduino) ist das 16 Bit, bei einem STM32 32 Bit.
Für jemanden der wenig/keine Ahnung von µC hat sehen diese Effekte verwirrend und buggy aus, jedoch ist das so im C Compiler hinterlegt. (so auch bei 32 / 64 Bit Programmen im PC!)
Die einzige Abhilfe ist die Datei
#include <stdint.h>
mit ein zu binden. Diese Datei definiert Integer Datentypen so, dass die auch genau das Format haben wie man will.
int8_t
int16_t
int32_t
int64_t
uint8_t
uint16_t
uint32_t
uint64_t
Und das ganze funktioniert garantiert, auch wenn man den Quellcode man von einem AVR >> STM32 µC portieren sollte, falls man doch mal feststellen sollte dass der AVR eine olle Krücke, die schon steinalt ist.
Merke: NIEMALS den Datenty int im µC UND PC verwenden!
Das Verhalten vom C Compiler ist schon so, seit dem es den ersten C Compiler gab.
Konstante:
1000 >> irgend ein int typ, der Compiler muss selbst was erfinden
1000L >> eine Konstante vom Typ "long"
1000UL >> eine Konstante vom Typ "unsigned long"
Um heraus zu finden wie viele bytes ein Datentyp belegt kann man das abfragen:
SizeOfDatentyp = sizeof(int); // beim AVR > 2 Byte, beim STM32 > 4 Byte
SizeOfDatentyp = sizeof(long); // beim AVR > 4 Byte, beim STM32 > 4 Byte
SizeOfDatentyp = sizeof(long long);
EleLa - Elektronik Lagerverwaltung - www.elela.de
-
- Beiträge: 294
- Registriert: So 4. Mai 2014, 21:32
- OS, Lazarus, FPC: Windows 10 64bit, Lazarus 2.0.10
- CPU-Target: 64bit
- Wohnort: Oranienburg
Re: C++ kann Verzweifelung verursachen
Hatte ich gar nicht mehr auf dem RadarSocke hat geschrieben:Marsmännchen hat geschrieben:Da ich nicht hardwarenah programmiere, bin ich bei ObjectPascal viel besser aufgehoben.
Auch mit dem FPC kann man hardwarenah programmieren: es werden verschiedene AVR- und ARM-Microcontroller sowie die x86-Architektur unterstützt. Wer also sein eigenes Betriebssystem in Pascal schreiben möchte, kann das gerne tun
Ich mag Pascal...
-
- Beiträge: 730
- Registriert: Di 23. Aug 2016, 14:25
- OS, Lazarus, FPC: Windows 11
- CPU-Target: 64Bit
- Wohnort: Berlin
Re: C++ kann Verzweifelung verursachen
Hallo MmVisual,
da Du Dich augenscheinlich gut in C auskennst, möcht ich gleich eine Frage dazu stellen,
Man vergebe mir, ist ja eigentlich nen Pascal-Forum...
Ich habe mir für meine C-Programme folgende Header Datei gebaut,
da ich es wesentlich leserlicher finde als die vielen Unterstriche der Typdefinitionen.
is es dann besser "sinnvoller" dass ich dies entsprechend ändere, also demnach:
löst das vielleicht auch die signed / unsigned Probleme bei Vergleichen mit gemischten Datentypen ?
Siro
da Du Dich augenscheinlich gut in C auskennst, möcht ich gleich eine Frage dazu stellen,
Man vergebe mir, ist ja eigentlich nen Pascal-Forum...
Ich habe mir für meine C-Programme folgende Header Datei gebaut,
da ich es wesentlich leserlicher finde als die vielen Unterstriche der Typdefinitionen.
Code: Alles auswählen
#ifndef Types_H_Included
#define Types_H_Included
#define FALSE (0) /* only the 0 is FALSE */
#define TRUE (!FALSE) /* all others are TRUE */
typedef unsigned char BOOL; /* 0=FALSE all others are TRUE */
typedef unsigned char U8; /* 8 Bit without sign */
typedef signed char S8; /* 8 Bit with sign */
typedef unsigned short U16; /* 16 Bit without sign */
typedef signed short S16; /* 16 Bit with sign */
typedef unsigned int U32; /* 32 Bit without sign */
typedef signed int S32; /* 32 Bit with sign */
typedef float F32; /* 32 Bit floating point ==> entspricht in Delphi dem Typ Single */
#endif
is es dann besser "sinnvoller" dass ich dies entsprechend ändere, also demnach:
Code: Alles auswählen
typedef uint8_t U8; /* 8 Bit without sign */
typedef int8_t S8; /* 8 Bit with sign */
typedef uint16_t U16; /* 16 Bit without sign */
typedef int16_t S16; /* 16 Bit with sign */
typedef uint32_t U32; /* 32 Bit without sign */
typedef int32_t S32; /* 32 Bit with sign */
löst das vielleicht auch die signed / unsigned Probleme bei Vergleichen mit gemischten Datentypen ?
Siro
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...
-
- Beiträge: 6164
- Registriert: Do 2. Jan 2014, 17:21
- OS, Lazarus, FPC: Linux (die neusten Trunk)
- CPU-Target: 64Bit
- Wohnort: Schweiz
Re: C++ kann Verzweifelung verursachen
is es dann besser "sinnvoller" dass ich dies entsprechend ändere, also demnach:
Ich würde dies auf jeden Fall machen, beim int hast du keine Garantie, das dieser 32Bit breit ist, auch nicht auf dem PC.
http://www.mrknowing.com/2013/10/08/dat ... ergroesse/
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot
Mit Java und C/C++ sehe ich rot
-
- Beiträge: 6164
- Registriert: Do 2. Jan 2014, 17:21
- OS, Lazarus, FPC: Linux (die neusten Trunk)
- CPU-Target: 64Bit
- Wohnort: Schweiz
Re: C++ kann Verzweifelung verursachen
Soner hat geschrieben:Der Gcc 4.9.2 liefert auch 50000.
Hier online compiler: http://cpp.sh/3qsgCode: Alles auswählen
// Example program
#include <iostream>
#include <string>
long getTime() {
int a = 50;
int b = 1000;
return a * b;
}
int main()
{
std::cout << getTime();
}
Beim GCC ist der int auch 32Bit breit und nicht nur 16Bit.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot
Mit Java und C/C++ sehe ich rot
-
- Beiträge: 1445
- Registriert: Fr 10. Okt 2008, 23:54
- OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
- CPU-Target: 32/64Bit
Re: C++ kann Verzweifelung verursachen
Binde das ein:
#include <stdint.h>
und erfinde nichts neues / eigenes. Die Datei ist bei jedem GCC irgendwo im lib/include Verzeichnis fix und fertig vorhanden.
Beschreibung z.B. hier:
http://pubs.opengroup.org/onlinepubs/00 ... int.h.html
#include <stdint.h>
und erfinde nichts neues / eigenes. Die Datei ist bei jedem GCC irgendwo im lib/include Verzeichnis fix und fertig vorhanden.
Beschreibung z.B. hier:
http://pubs.opengroup.org/onlinepubs/00 ... int.h.html
EleLa - Elektronik Lagerverwaltung - www.elela.de
-
- Beiträge: 369
- Registriert: Do 8. Jun 2017, 18:21
- OS, Lazarus, FPC: Windows 10 64bit, Lazarus 2.0.10, FPC 3.2.0
- CPU-Target: 64Bit
- Wohnort: Wien
Re: C++ kann Verzweifelung verursachen
Code: Alles auswählen
#define FALSE (0) /* only the 0 is FALSE */
#define TRUE (!FALSE) /* all others are TRUE */
Der Kommentar ist jedenfalls irreführend, weil diese Definition macht true synonym zu 1, und natürlich nicht Synonym zu "all others" - so etwas ist ja gar nicht möglich.
-
- Beiträge: 623
- Registriert: Do 27. Sep 2012, 00:07
- OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
- CPU-Target: x86_64-win64
- Wohnort: Hamburg
Re: C++ kann Verzweifelung verursachen
braunbär hat geschrieben:Code: Alles auswählen
#define FALSE (0) /* only the 0 is FALSE */
#define TRUE (!FALSE) /* all others are TRUE */
Der Kommentar ist jedenfalls irreführend, weil diese Definition macht true synonym zu 1, und natürlich nicht Synonym zu "all others" - so etwas ist ja gar nicht möglich.
Ich glaube schon das der Kommentar richtig ist.
In C und C++ ist Ausrufezeichen '!' not-Operator, also 'not 0' heißt dann alle Zahlen die nicht Null sind.
- m.fuchs
- Lazarusforum e. V.
- Beiträge: 2636
- Registriert: Fr 22. Sep 2006, 19:32
- OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
- CPU-Target: x86, x64, arm
- Wohnort: Berlin
- Kontaktdaten:
Re: C++ kann Verzweifelung verursachen
Soner hat geschrieben:Ich glaube schon das der Kommentar richtig ist.
In C und C++ ist Ausrufezeichen '!' not-Operator, also 'not 0' heißt dann alle Zahlen die nicht Null sind.
Von der Logik her her würde ich dir zustimmen. Allerdings ist im C-Standard etwas anderes definiert:
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf hat geschrieben:The result of the logical negation operator ! is 0 if the value of its operand compares
unequal to 0, 1 if the value of its operand compares equal to 0.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
-
- Beiträge: 730
- Registriert: Di 23. Aug 2016, 14:25
- OS, Lazarus, FPC: Windows 11
- CPU-Target: 64Bit
- Wohnort: Berlin
Re: C++ kann Verzweifelung verursachen
Guten Morgen zusammen,
Alles außer 0 ist doch "true" weil eine Abfrage:
if (x).... führt die Anweisung NUR dann aus, wenn x NICHT 0 ist.
Also auch wenn x -12 oder +2456 ist.
somit ist die Deklaration von TRUE = (! FALSE) doch korrekt.
Falsch wäre es, wenn ich #define TRUE (1) schreiben würde.
Dann wäre eine -12 oder +2456 plötzlich FALSE, was dem Ablauf von if (x) wiedersprechen würde.
.....
Deklaration / Definition ist auch so eine Wortspielerei....
ein #define ist nicht etwa eine Definition, sondern eine Deklaration
da fragt man sich auch was das soll....
Es gab mal eine Sprache, da hiess eine Deklarartion sinnvollerweise auch "DECLARE" PL/M-80 falls das noch jemand kennt, ist schon ein bischen her
kommt aber dem Pascal SEHR nahe.
Siro
Eine schöne "C" Mecker Ecke hier....
Alles außer 0 ist doch "true" weil eine Abfrage:
if (x).... führt die Anweisung NUR dann aus, wenn x NICHT 0 ist.
Also auch wenn x -12 oder +2456 ist.
somit ist die Deklaration von TRUE = (! FALSE) doch korrekt.
Falsch wäre es, wenn ich #define TRUE (1) schreiben würde.
Dann wäre eine -12 oder +2456 plötzlich FALSE, was dem Ablauf von if (x) wiedersprechen würde.
.....
Deklaration / Definition ist auch so eine Wortspielerei....
ein #define ist nicht etwa eine Definition, sondern eine Deklaration
da fragt man sich auch was das soll....
Es gab mal eine Sprache, da hiess eine Deklarartion sinnvollerweise auch "DECLARE" PL/M-80 falls das noch jemand kennt, ist schon ein bischen her
kommt aber dem Pascal SEHR nahe.
Siro
Eine schöne "C" Mecker Ecke hier....
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...
-
- Beiträge: 369
- Registriert: Do 8. Jun 2017, 18:21
- OS, Lazarus, FPC: Windows 10 64bit, Lazarus 2.0.10, FPC 3.2.0
- CPU-Target: 64Bit
- Wohnort: Wien
Re: C++ kann Verzweifelung verursachen
Eine Konstantendeklaration hat den Sinn, eine Bezeichnung einzuführen, die in der Folge im Programm beliebig an Stelle des angegebenen Werts verwendet werden kann.
Die Konstante FALSE kann im Programm beliebig an Stelle des Werts 0 verwendet werden.
Die Konstante TRUE kannst du aber im Programm nur bei Zuweisunngen verwenden, if (b==true) wird ein falsches (unerwartetes) Ergebnis liefern, wenn man sie dem Kommentar folgend verwendet.
Denn if (b==true) bedeutet etwas ganz anderes als !(b==false). Wenn du schreibst
dann ist kein Missverständnis möglich. Der Fehler, boolean Variable auf Gleichheit mit boolean Konstanten zu vergleichen, kommt vor allem bei Anfängern sehr häufig vor, und kann auch in Pascal zu Problemen führen. Deshalb mein Hinweis.
in C heißt es übrigens #define, weil mit der Zeile eine Variable nicht nur deklariert, sondern auch gleich definiert wird. Es steht ja in der Zeile, was die Variable FALSE bedeutet.
Die Konstante FALSE kann im Programm beliebig an Stelle des Werts 0 verwendet werden.
Die Konstante TRUE kannst du aber im Programm nur bei Zuweisunngen verwenden, if (b==true) wird ein falsches (unerwartetes) Ergebnis liefern, wenn man sie dem Kommentar folgend verwendet.
Denn if (b==true) bedeutet etwas ganz anderes als !(b==false). Wenn du schreibst
Code: Alles auswählen
#define FALSE (0) /* only the 0 is FALSE */
#define TRUE (1) /* any other value different from 0 also means TRUE */
dann ist kein Missverständnis möglich. Der Fehler, boolean Variable auf Gleichheit mit boolean Konstanten zu vergleichen, kommt vor allem bei Anfängern sehr häufig vor, und kann auch in Pascal zu Problemen führen. Deshalb mein Hinweis.
in C heißt es übrigens #define, weil mit der Zeile eine Variable nicht nur deklariert, sondern auch gleich definiert wird. Es steht ja in der Zeile, was die Variable FALSE bedeutet.
-
- Beiträge: 1445
- Registriert: Fr 10. Okt 2008, 23:54
- OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
- CPU-Target: 32/64Bit
Re: C++ kann Verzweifelung verursachen
braunbär hat geschrieben:in C heißt es übrigens #define, weil mit der Zeile eine Variable nicht nur deklariert, sondern auch gleich definiert wird. Es steht ja in der Zeile, was die Variable FALSE bedeutet.
Bitte "C" Fragen nicht in einem Pascal Forum posten. Da bekommt man viele falsche Antworten.
das #define ist ein Präprozessor direktive, da läuft ein Parser durch den Code und ersetzt alle Texte "FALSE" in "(0)", nichts anderes. Erst danach geht der so manipulierte Code zum C Compiler, der sieht dann die (0) und nicht mehr FALSE. Da wird weder eine Variable deklariert noch Speicher angelegt.
EleLa - Elektronik Lagerverwaltung - www.elela.de
-
- Beiträge: 369
- Registriert: Do 8. Jun 2017, 18:21
- OS, Lazarus, FPC: Windows 10 64bit, Lazarus 2.0.10, FPC 3.2.0
- CPU-Target: 64Bit
- Wohnort: Wien
Re: C++ kann Verzweifelung verursachen
Du hast Recht, aber im Endeffekt läuft es (zumindest in so einfachen Fällen) auf die Definition einer Konstanten hinaus. ""Variable" war das falsche Wort, richtig wäre "Bezeichner" gewesen.
Erst wollte ich schreiben, #define definiert ein Makro - das wäre wohl besser gewesen. Ich wollte es aber nicht weiter komplizieren.
Jedenfalls handelt es sich bei #define um eine Definition und nicht nur um eine Deklaration, denn aus der Zeile ergibt sich die Bedeutung des Namens.
Konstantendefinitionen legen generell keinen Speicher an, außer im Fall von typed constants.
Erst wollte ich schreiben, #define definiert ein Makro - das wäre wohl besser gewesen. Ich wollte es aber nicht weiter komplizieren.
Jedenfalls handelt es sich bei #define um eine Definition und nicht nur um eine Deklaration, denn aus der Zeile ergibt sich die Bedeutung des Namens.
Konstantendefinitionen legen generell keinen Speicher an, außer im Fall von typed constants.
-
- Beiträge: 6164
- Registriert: Do 2. Jan 2014, 17:21
- OS, Lazarus, FPC: Linux (die neusten Trunk)
- CPU-Target: 64Bit
- Wohnort: Schweiz
Re: C++ kann Verzweifelung verursachen
Alles außer 0 ist doch "true" weil eine Abfrage:
if (x).... führt die Anweisung NUR dann aus, wenn x NICHT 0 ist.
Also auch wenn x -12 oder +2456 ist.
somit ist die Deklaration von TRUE = (! FALSE) doch korrekt.
Falsch wäre es, wenn ich #define TRUE (1) schreiben würde.
Dann wäre eine -12 oder +2456 plötzlich FALSE, was dem Ablauf von if (x) wiedersprechen würde.
Ist das in Pascal nicht auch so ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot
Mit Java und C/C++ sehe ich rot
- m.fuchs
- Lazarusforum e. V.
- Beiträge: 2636
- Registriert: Fr 22. Sep 2006, 19:32
- OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
- CPU-Target: x86, x64, arm
- Wohnort: Berlin
- Kontaktdaten:
Re: C++ kann Verzweifelung verursachen
Mathias hat geschrieben:if (x).... führt die Anweisung NUR dann aus, wenn x NICHT 0 ist.
Also auch wenn x -12 oder +2456 ist.
Ist das in Pascal nicht auch so ?
Nein, da kann man keine Zahl als Prüfbedingung für ein if verwenden.
Code: Alles auswählen
Error: Incompatible types: got "ShortInt" expected "Boolean"
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de