Hallo allerseits, In Arduino soll boolean ein Bit sein. Ich habe Zweifel und vermute eher, dass es ein byte (char) ist. Die Sache ist, ich arbeite mit Statusregistern. 1 Byte sind also 8 Flags. Wenn ein boolean vom Arduino intern aber schon als Bit verwaltet wird, kann ich mir die Bitarithmetik sparen und die Werte direkt abfragen. Habe leider bisher keine eindeutigen Infos gefunden.
Roth schrieb: > In Arduino soll boolean ein Bit sein. Ich habe Zweifel und vermute eher, > dass es ein byte (char) ist. Zweifel ist gut, vermuten bringt dich nicht weiter. Guck nach, wie der Datentyp bool definiert ist oder was im LST-File bei Verwendung von Bool-Variablen passiert.
Wolfgang schrieb: > Zweifel ist gut, vermuten bringt dich nicht weiter. Stimmt :-) > Guck nach, wie der Datentyp bool definiert ist oder was im LST-File bei > Verwendung von Bool-Variablen passiert. WO soll ich nachsehen? Wo steht, von welchem Typ boolean abgeleitet wird?
Der avr-gcc Compiler, den Arduino verwendet, belegt ein ganzes Byte für boolean Werte.
So geht das mit 1bool->1bit
1 | struct flags_t { |
2 | bool f1:1; |
3 | bool f2:1; |
4 | bool f3:1; |
5 | bool f4:1; |
6 | bool f5:1; |
7 | bool f6:1; |
8 | bool f7:1; |
9 | bool f8:1; |
10 | } flags; |
11 | |
12 | void foo() { |
13 | if(flags.f3) { |
14 | flags.f8 = true; |
15 | }
|
16 | }
|
Nennt sich bitfield und wird je nach Arduino (AVR oder ARM, opcodes anderer kenne ich nicht gut genug) zumindest im Falle von einzelnen Bits recht kompakten Code erzeugen.
Arduino Fanboy D. schrieb: > stdbool.h Da wird leider nur bool definiert. Ich meine konkret boolean Die Werte (0 1) sind mir klar. Es ging mir um die Organisation im Speicher, ob 0/1 als byte abgelegt wird oder ob der Compiler Flags verwaltet, und die Werte bit-orientiert speichert. Und genau DAS kann ich mir nicht vorstellen. Im Internet fand ich aber Stellen, wo leider das behauptet wird. Stefanus F. schrieb: > Der avr-gcc Compiler, den Arduino verwendet, belegt ein ganzes Byte für > boolean Werte. Ja, ganau das meine ich.
Die kleinste adressierbare Objektgröße in C ist ein Byte/char. Es gibt keine Bitvariablen. Die Frage sollte also eher lauten: ist ein Bool eine 8-, 16- oder 32-Bit Größe? Das sagt dir der sizeof-Operator. Und nicht von Bitfeldern irritieren lassen: dass ist ein aufgesetzter Hack, der einzelnen Bits innerhalb eines Objekts Namen gibt - Bitfelder sind keine eigenständigen Objekte. Am besten ignorieren.
Roth schrieb: > WO soll ich nachsehen? Wo steht, von welchem Typ boolean abgeleitet > wird? Da du Arduino nutzt wird der C++ Compiler (default) verwendet. Also koenntest du in der C++ Referenz nachschauen. https://en.cppreference.com/w/cpp/language/types
1 | Boolean type |
2 | |
3 | bool - type, capable of holding one of the two values: true or false. |
4 | The value of sizeof(bool) is implementation defined and might differ from 1. |
Roth schrieb: > Da wird leider nur bool definiert. Ich meine konkret boolean Sorry, aber du stellst dich schon etwas an, oder? Oder du benutzt C++ und Arduino...wie waere es mal da nachzusehen? https://www.arduino.cc/reference/en/language/variables/data-types/boolean/
1 | boolean is a non-standard type alias for bool defined by Arduino. It’s |
2 | recommended to instead use the standard type bool, which is identical. |
foobar schrieb: > Und nicht von Bitfeldern irritieren lassen: dass ist ein aufgesetzter > Hack, der einzelnen Bits innerhalb eines Objekts Namen gibt - Bitfelder > sind keine eigenständigen Objekte. Am besten ignorieren. Ich finde C(...) toll. Gesammelt Hacks aus 40 Jahren Sprachentwicklung und nur die guten Sitten regeln, was sich schickt, zu verwenden.
foobar schrieb: > Und nicht von Bitfeldern irritieren lassen: dass ist ein aufgesetzter > Hack, der einzelnen Bits innerhalb eines Objekts Namen gibt - Bitfelder > sind keine eigenständigen Objekte. Am besten ignorieren. Ich vermute das auch. Aber C/C++ ist nicht das, womit ich jeden Tag zu tun habe. Gefragt habe ich, weil ich mir vorstellen kann (wenn man das will), dass ein Compiler/Parser Flags (bool, Boolean) als Bit ablegt. Auf ASM-Ebene dürften Bitzugriffe kaum mehr Programmcode erzeugen als Zugriffe auf Bates. Ich kenne aber den Befehlssatz der CPU nicht, und daher ist auch das eine Vermutung. OK, danke an alle :-)
> bool - type, capable of holding one of the two values: true or > false. The value of sizeof(bool) is implementation defined and > might differ from 1. > boolean is a non-standard type alias for bool defined by Arduino. > It’s recommended to instead use the standard type bool, > which is identical. Das sagt doch auch nicht aus, wie viel Speicher dabei tatsächlich belegt wird. Wie gesagt: Es ist ein Byte. Und zwar obwohl die CPU durchaus auch einzelne Bits unterstützt - leider nur in den I/O Registern, falls ich mich nicht irre. Es gibt aber andere CPU's die auch Bits im RAM adressieren können, trotzdem wird das dort vom gcc nicht unterstützt.
> Nennt sich bitfield und wird je nach Arduino (AVR oder ARM, opcodes > anderer kenne ich nicht gut genug) zumindest im Falle von einzelnen > Bits recht kompakten Code erzeugen. Dummerweise sind Bitfields so schwach definiert, dass man sie kaum sinnvoll nutzen kann. Weder ist die Reihenfolge noch das Packing definiert. So könnte in deinem Beispiel das Feld f1 das höchst- oder das niederwertigste Bit sein, oder gar jedes Feld ein einzelnes Byte/Word belegen. Da sie außerdem nicht adressierbar sind (&-Operator), sind sie irgendwie eine Fremdkörper im System - ein schwarzes Schaf ;-)
> Fremdkörper
trifft es gut. Zwar kann z.B. der arm-gcc sogar das Bit-banding
irgendwie nutzen, aber ziemlich umständlich, eingeschränkt und eben
nicht mit booleans.
> Gesammelt Hacks aus 40 Jahren Sprachentwicklung und nur die guten > Sitten regeln, was sich schickt, zu verwenden. Gut dem normalen Leben abgeschaut, nicht wahr? ;-)
Kaj schrieb: > Sorry, aber du stellst dich schon etwas an, oder? Nö. Kaj schrieb: > boolean is a *non standard type*
Wo gibts denn diese gegammelten Hacks?
> weil ich mir vorstellen kann (wenn man das will), dass ein > Compiler/Parser Flags (bool, Boolean) als Bit ablegt. Die C-Compiler tuen sich schwer, die Bit-Befehle von Prozessoren sinnvoll zu nutzen. Die Sprache bietet kaum Elemente, um mit einzelnen Bits zu arbeiten und es ist viel Analyse notwendig, um festzustellen, ob im konkreten Fall mit Bit-Operationen das gewünschte Ziel erreicht werden kann.
Stefanus F. schrieb: > Und zwar obwohl die CPU durchaus auch einzelne Bits unterstützt - leider > nur in den I/O Registern, falls ich mich nicht irre. Das hängt natürlich von der CPU/MCU ab. Es war keine konkrete genannt, nur "Arduino". Falls "Arduino" aber im konkreten Fall AVR8 meint, dann irrst du und zwar gleich mehrfach. Zum einen werden Bitzugriffe auf dieser Architektur längst nicht für alle I/O-Register unterstützt, sondern nur für die mit einer Adresse < 0x20. (Asm rules: sbi, cbi, sbic, sbis. Refer "instruction set reference manual") Zum anderen werden zumindest lesende Bitzugriffe auch für alle MCU-Register unterstützt (Asm rules: sbrs, sbrc. Refer "instruction set reference manual"). > Es gibt aber andere > CPU's die auch Bits im RAM adressieren können, trotzdem wird das dort > vom gcc nicht unterstützt. Das nur insofern wahr, als dass der gcc tatsächlich keinen boolean-Typ bietet, der aus einem einzelnen Bit besteht. Weil dieses Drecks-C schon vom Konzept her so etwas nicht vorsieht. Schuld ist also nicht der gcc, sondern das vieler Hinsicht unsägliche Grundkonzept von C. Auf der anderen Seite bemüht sich der gcc allerdings durchaus, mit Bitoperationen zu arbeiten, wenn das Zielsystem solche anbietet. Der Workaround um die grundsätzliche Unfähigkeit von C ist halt, mit Bitfields zu arbeiten, wenn man Bits braucht.
foobar schrieb: >> Nennt sich bitfield und wird je nach Arduino (AVR oder ARM, opcodes >> anderer kenne ich nicht gut genug) zumindest im Falle von einzelnen >> Bits recht kompakten Code erzeugen. > > Dummerweise sind Bitfields so schwach definiert, dass man sie kaum > sinnvoll nutzen kann. Weder ist die Reihenfolge noch das Packing > definiert. So könnte in deinem Beispiel das Feld f1 das höchst- oder das > niederwertigste Bit sein, oder gar jedes Feld ein einzelnes Byte/Word > belegen. Da sie außerdem nicht adressierbar sind (&-Operator), sind sie > irgendwie eine Fremdkörper im System - ein schwarzes Schaf ;-) Es ist sogar nicht mal festgelegt ob int 1er oder 2er-Komplement benutzt, deshalb kann man ja eigentlich C gar nicht verwenden. Wen interessiert wo die 8 bool, die man in ein Byte packen kann, stehen. Es wurde nicht von Device-Register gesprochen, sondern einfach von mehreren Flags. Die funktionieren auch wenn man deren Adresse nicht ermitteln kann. Sogar wenn man nicht daran glaubt.
c-hater schrieb: > Weil dieses Drecks-C schon vom Konzept her so etwas nicht vorsieht. Ich habe Dich schon mehrfach gebeten, Dein unsachlichen und unendlich dümmlichen Kommentare zu unterlassen. Weil es Dich intellektuell überfordert, zu verstehen, was C ist und was man damit machen kann, musst Du das hier nicht in epischer Breite überall im Forum breittreten. Nimm halt Deinen Pascal/Basic/Fortran/Wasauchimmer-Compiler und freu' Dich im stillen Kämmerlein darüber.
Als Grunddatentyp ausserhalb von Bitfeldern ist ein einzelnes Bit schon deshalb schwer in den C Standard integrierbar, weil Bits auf Hardware-Ebene üblicherweise keine individuelle Adresse haben (*) und sizeof(char) auf 1 definiert ist. *: Eine Ausnahme davon ist ARMs Bitbanding. foobar schrieb: > Die C-Compiler tuen sich schwer, die Bit-Befehle von Prozessoren > sinnvoll zu nutzen. Das ist im Prinzip schon lange kein Thema mehr. Wobei manche Hardware aus grauer Vorzeit allerdings nur effizient umsetzbar ist, wenn man ein Auge zudrückt. So sind AND/OR Operationen von 8051 mit Ports als Ziel aufgrund ihrer recht spezieller Arbeitsweise eigentlich nicht mit dem C Standard vereinbar, trotzdem werden sie natürlich genutzt. Da kann aber C nicht viel für, die 8051 ISA war für Assembler gebaut.
:
Bearbeitet durch User
Carl D. schrieb: > Es ist sogar nicht mal festgelegt ob int 1er oder 2er-Komplement > benutzt, Das wird vielleicht verständlicher, wenn man die Entstehungszeit von C betrachtet. Die damals leistungsfähigsten Rechner arbeiteten im Einerkomplement und deren Derivate wurden bis in die 80er eingesetzt. Das Zweierkomplement war also mitnichten selbstverständlich.
:
Bearbeitet durch User
Rufus Τ. F. schrieb: > Weil es Dich intellektuell überfordert, Ach, das darfst du nicht zu ernst nehmen... An und für sich, scheint unser C Hasser, in Sachen AVR, einiges an Kompetenz zu haben. Bei Arduino hapert es dann schon etwas. Denn das ist kein C sondern eher C++. Aber das ist ihm nicht klar, oder ist ihm egal.(und mir eigentlich auch) Aber wo es noch mehr und deutlicher hapert, findet sich im Bereich seiner sozialen Kompetenz. Im urteilen ganz schnell... verzeihen sieht man eher selten, bis gar nicht. Und wenn das so unausgeglichen ist, kann man schon von einem Defekt aus gehen. Denn eigentlich sollte sich verzeihen und urteilen die Waage halten. --- Liebster Rufus, nicht, dass ich deinen Appell nicht verstehen würde, aber er ist für die Katz. Versuche doch mal einem dummen Menschen zu sagen: "Jetzt stelle dich mal etwas klüger an!" Das funktioniert nicht. Selbst bei Einsicht nicht. Andersrum, vielleicht... aber so rum nicht.
Carl D. schrieb: > Es ist sogar nicht mal festgelegt ob int 1er oder 2er-Komplement > benutzt, deshalb kann man ja eigentlich C gar nicht verwenden. NB: In welcher vergleichbar alten Sprache ist das eigentlich auf Zweierkomplement festgelegt? In Wirth'schem Pascal ganz sicher nicht.
A. K. schrieb: > Carl D. schrieb: >> Es ist sogar nicht mal festgelegt ob int 1er oder 2er-Komplement >> benutzt, > > Das wird vielleicht verständlicher, wenn man die Entstehungszeit von C > betrachtet. Die damals leistungsfähigsten Rechner arbeiteten im > Einerkomplement und deren Derivate wurden bis in die 80er eingesetzt. > Das Zweierkomplement war also mitnichten selbstverständlich. Ich weiß. Nur machen sich manche Sorgen macht, daß ein Bit explodieren könnte, weil seine Position im Byte nicht implementierungsunabhängig festgelegt ist, aber sie bedenkenlos mit Zahlen rechnen, deren Format auch nicht wesentlich genauer festgeschrieben ist, dann könnte man an deren Verstand zweifeln.
foobar schrieb: > Die C-Compiler tuen sich schwer, die Bit-Befehle von Prozessoren > sinnvoll zu nutzen. Die Sprache bietet kaum Elemente, um mit einzelnen > Bits zu arbeiten Meinst du das wirklich ernst? Bei C gibts Bit-Operatoren wie in kaum in einer anderen Sprache. ASM und noch ein paar ausgenommen. Aber sicher meinst du was anderes, z.B. die Umsetzung der Bit-Befehle in Opcode. Das weiß ich bei diesem Prozessortyp (Arduino, AtMega, AVR) nicht. Aber genau darauf zielte meine Frage ab. Ich lass das jetzt aber sein mit Bitschieberei. Bringt weder Platz im Speicher noch Übersicht in (meinem) Programm. Mich würde trotzdem nochmal interessieren, wieso eurer Aussage nach "einzelne Bits [im Opcode?] nicht unterstützt werden", wenn die (Hoch)Sprache (C) so viele Bitbefehle unterstützt https://de.wikipedia.org/wiki/Bitweiser_Operator Stefanus F. schrieb: > Und zwar obwohl die CPU durchaus auch einzelne Bits unterstützt - leider > nur in den I/O Registern, falls ich mich nicht irre.
Du solltest deinen eigenen Compiler bauen! (alternativ, die Doku zu dem lesen, welchen du nutzt)
> Nur machen sich manche Sorgen macht, daß ein Bit explodieren könnte, > weil seine Position im Byte nicht implementierungsunabhängig festgelegt > ist, Das kommt wohl daher, dass in den meisten Fällen Bitfields für die Beschreibung von existierenden Datenstrukturen (Hardwareregister/Datenprotokolle/etc) eingesetzt werden[1] und dann solche Konstrukte entstehen (aus <netinet/tcp.h>):
1 | /*
|
2 | * TCP header.
|
3 | * Per RFC 793, September, 1981.
|
4 | */
|
5 | struct tcphdr |
6 | {
|
7 | u_int16_t source; |
8 | u_int16_t dest; |
9 | u_int32_t seq; |
10 | u_int32_t ack_seq; |
11 | # if __BYTE_ORDER == __LITTLE_ENDIAN
|
12 | u_int16_t res1:4; |
13 | u_int16_t doff:4; |
14 | u_int16_t fin:1; |
15 | u_int16_t syn:1; |
16 | u_int16_t rst:1; |
17 | u_int16_t psh:1; |
18 | u_int16_t ack:1; |
19 | u_int16_t urg:1; |
20 | u_int16_t res2:2; |
21 | # elif __BYTE_ORDER == __BIG_ENDIAN
|
22 | u_int16_t doff:4; |
23 | u_int16_t res1:4; |
24 | u_int16_t res2:2; |
25 | u_int16_t urg:1; |
26 | u_int16_t ack:1; |
27 | u_int16_t psh:1; |
28 | u_int16_t rst:1; |
29 | u_int16_t syn:1; |
30 | u_int16_t fin:1; |
31 | # else
|
32 | # error "Adjust your <bits/endian.h> defines"
|
33 | # endif
|
34 | u_int16_t window; |
35 | u_int16_t check; |
36 | u_int16_t urg_ptr; |
37 | };
|
[1] und vermutlich sogar ursprünglich dafür gedacht waren.
Arduino Fanboy D. schrieb: > Du solltest deinen eigenen Compiler bauen! Sorge dich nicht, das habe ich schon. Allerdings immer in Assembler. Da taten sich solche Probleme gar nicht erst auf bzw. konnten mit der Tastatur in allen mir bekannten Fällen vermieden werden. Arduino Fanboy D. schrieb: > (alternativ, die Doku zu dem lesen, welchen du nutzt) Wenn du mir die Doku einer Hochsprache zeigst, die fragebeantwortend darauf eingeht, in welcher Form ein Compiler die Datenstruktur im RAM oder Heap organisiert, kröne ich dich zum Helden im Leben der Hochsprachen. Solche Infos findet man nicht "in der Doku", sondern nur in (sehr speziellen) Fachbüchern zu dieser Sprache.
Roth schrieb: > In Arduino soll boolean ein Bit sein. Ich habe Zweifel und vermute eher, > dass es ein byte (char) ist. Es kommt auf den Kontext an, wieviel Platz "ein boolean" belegt. Zuerst mal: es gibt keine Programmiersprache namens "Arduino". Die Programmiersprache heißt C++ und Arduino liefert lediglich einen Sack Funktionen zur Hardwareabstraktion (etwa digitalWrite()). Folglich ist deine Frage: "wieviel Platz braucht eine boolean Variable in C++?" Jetzt kommen wir zum oben genannten Kontext. C/C++ hat als kleinste adressierbare Einheit das Byte (das übrigens auch mehr als 8 Bit haben darf). Eine einzelne boolean Variable wird also (mindestens) ein Byte belegen. Der C++ Standard legt das nicht fest, die Größe einer boolean Variable ist "implementation defined". Anders sieht es aus, wenn du einen Container mit boolean Variablen betrachtest, bspw. std::vector<bool> oder std::bitset oder std::array<bool>. Hier ist es zwar immer noch implementation defined, aber alle mir bekannten Implementierungen haben eine platzoptimierte Variante des Containers für boolean. > Die Sache ist, ich arbeite mit Statusregistern. 1 Byte sind also 8 > Flags. Wenn ein boolean vom Arduino intern aber schon als Bit verwaltet > wird, kann ich mir die Bitarithmetik sparen und die Werte direkt > abfragen. Irgendwie ergibt dieser Teil der Frage keinen rechten Sinn. Statusregister, die 8 Bits enthalten, wird man in einer uint8_t Variable halten bzw. bearbeiten. Ich sehe hier niergends boolean ins Spiel kommen. Zur Abfrage einzelner Bits in einer solchen Variable hat C/C++ leistungsfähige Operatoren. Siehe Bitmanipulation
:
Bearbeitet durch User
Roth schrieb: > Wenn du mir die Doku einer Hochsprache zeigst, die fragebeantwortend > darauf eingeht, in welcher Form ein Compiler die Datenstruktur im RAM > oder Heap organisiert, Da es hier eher um das Layout von Datenstrukturen, Bits und Bitfeldern geht, nicht um Heapverwaltung: Ada geht recht weit darin, das im Quellcode explizit angeben zu können.
:
Bearbeitet durch User
Ich begreife es nicht... Eine Hochsprache dient doch gerade dazu solche Details zu verbergen/abstrahieren. Das ist doch Teil des Sinns ihrer Existenz. OK. C/C++ gilt als Maschinennah, und erlaubt Bitgefummel auf niedrigster Ebene. Aber auf Sprachebene ist das doch alles wurscht. Leitsatz: Programmiere immer nur gegen das Interface, nie gegen die Implementierung. Gilt auch für diesen Fall.
Arduino Fanboy D. schrieb: > Ein Hochsprache dient doch gerade dazu solche Details zu verbergen. > Das ist doch Teil des Sinns ihrer Existenz. Die exakte Repräsentation von Daten kann für ein Programm entscheidend sein. Wenn 2 Rechner über TCP/IP miteinander kommunizieren, ist es nicht ganz unwichtig, dass die Repräsentation auf beiden Seiten exakt gleich ist. Präzise Beschreibung ist an dieser Stelle angesagt, nicht Abstraktion. Ich hatte vorhin Ada genannt. Diese Sprache wurde für embedded Anwendungen konzipiert und enthält daher diese Möglichkeit, die Repräsentation von Daten explizit beschreiben zu können.
A. K. schrieb: > Als Grunddatentyp ausserhalb von Bitfeldern ist ein einzelnes Bit schon > deshalb schwer in den C Standard integrierbar, weil Bits auf > Hardware-Ebene üblicherweise keine individuelle Adresse haben (*) und > sizeof(char) auf 1 definiert ist. Da andere Sprachen wie Ada, Pascal das aber durchaus können, scheint es nicht an der Hardware zu hängen, sondern eher an: Scheissdrauf, schmeissen wir halt 7 oder 15 Bits weg, wen juckts. Arduino Fanboy D. schrieb: > Bei Arduino hapert es dann schon etwas. > Denn das ist kein C sondern eher C++. Was die Sache an der Stelle auch nicht besser macht. Roth schrieb: > Aber sicher meinst du was anderes, z.B. die Umsetzung der Bit-Befehle in > Opcode. Das weiß ich bei diesem Prozessortyp (Arduino, AtMega, AVR) > nicht. Aber genau darauf zielte meine Frage ab. Mal ne richtige Programmiersprache:
1 | terror = bitpacked record // Errorflags |
2 | case byte of |
3 | 0 : (rtc, // Flag Fehler RTC |
4 | twi, // Flag Fehler TWI |
5 | eeprom, // Flag Fehler EEPROM |
6 | bit3, bit4, bit5, bit6, |
7 | sens : boolean); // Flag Fehler Sensor |
8 | 1 : (all : uint8); |
9 | end; |
Und damit geht dann sowas:
1 | error.sens := true; |
2 | ... |
3 | if error.sens then begin |
Was kompiliert wird zu:
1 | lds r18,(U_sHVS_DEFINE_ss_ERROR) |
2 | ori r18,-128 |
3 | sts (U_sHVS_DEFINE_ss_ERROR),r18 |
4 | ... |
5 | lds r18,(U_sHVS_DEFINE_ss_ERROR) |
6 | sbrs r18,7 |
7 | rjmp .Lj343 |
8 | oder |
9 | lds r18,(U_sHVS_DEFINE_ss_ERROR) |
10 | andi r18,-128 |
11 | breq .Lj347 |
Besser bekommst Du das auch in Assembler nur hin, wenn Du die Flags in einem Register hältst.
Karl schrieb: > Was die Sache an der Stelle auch nicht besser macht. Ich stufe den Roth mittlerweile als Troll ein. Ein selbst ernannter Compilerbauer, welcher die C Operatoren nicht versteht, oder verstehen will. Das geht nicht zusammen.
Karl schrieb: > Da andere Sprachen wie Ada, Pascal das aber durchaus können, scheint es > nicht an der Hardware zu hängen, sondern eher an: Scheissdrauf, > schmeissen wir halt 7 oder 15 Bits weg, wen juckts. Eine Sprache der Bedeutung von C ist in ihrer Grundstruktur festbetoniert. Änderungen, die in signifikantem Umfang mit bestehendem Code brechen, wird es nicht mehr geben. Friss oder stirb - wenn du nicht damit leben kannst, dann schmeiss es weg und nimm was anderes. Dass sich verschiedene Programmiersprachen unterscheiden liegt in der Natur der Sache. Sonst wären sie nicht verschieden. Das gilt auch für Sprachen mit zumindest ursprünglich ähnlichem Einsatzzweck. Ada wurde ausdrücklich für embedded Anwendungen konzipiert. Keine Sprachen war im damaligen Chaos als befriedigend angesehen worden, C verständlicherweise eingeschlossen. Leider half es nichts, gegen C kam es nicht an. Die Vorteile von C liegen heute nicht in der Qualität der Sprache, sondern in der Verbreitung und Verfügbarkeit, der Existenz auf so ziemlich allen Plattformen. Und im bestehenden Quellcode.
:
Bearbeitet durch User
Arduino Fanboy D. schrieb: > Ein selbst ernannter Compilerbauer, welcher die C Operatoren nicht > versteht, oder verstehen will. > Das geht nicht zusammen. Doch. Man kann Compiler schreiben, ohne C zu verwenden, und es müssen keine C Compiler sein. Dann muss man von C auch keine Ahnung haben. Allerdings würde ich, anders als er, dafür ganz sicher nicht Assembler verwenden. ;-)
:
Bearbeitet durch User
A. K. schrieb: > Als Grunddatentyp ausserhalb von Bitfeldern ist ein einzelnes Bit schon > deshalb schwer in den C Standard integrierbar, weil Bits auf > Hardware-Ebene üblicherweise keine individuelle Adresse haben Dem stimme ich nicht zu. So wie alle Datentypen könnte ein Compiler genausogut ein Bit im Speicher anlegen. Indem er ein Byte anlegt und es mit 8 Bits füllt, und diese als Variable, Kontante (wie auch immer) referenziert. Wenn das Byte erschöpft ist, 8 Bit wurde addressiert, wird das nächste Byte angelegt. Das nennt sich Speichermanagement, was soll daran "schwer integrierbar" sein ?
Roth schrieb: > was soll daran "schwer integrierbar" sein ? Also sizeof(bit) == 0.125? Diese Milch wurde vor zig Jahren verschüttet und du kriegst diesen Käse nicht mehr in die Flasche zurück. C hat bestimmte Grundstrukturen. Natürlich kannst du eine Sprache bauen, die so arbeitet, wie du es gerne hättest. Aber das wäre kein C (oder C++) im Sinn des Standards. Wenn du also nicht deine eigene Sprache entwickeln willst: "You program with the language you have, not the language you might want or wish to have at a later time." (frei nach Donald)
:
Bearbeitet durch User
Arduino Fanboy D. schrieb: > Ich stufe den Roth mittlerweile als Troll ein. > Ein selbst ernannter Compilerbauer, welcher die C Operatoren nicht > versteht, oder verstehen will. > Das geht nicht zusammen. Lass deine selbstprofilierenden Sprüche einfach sein! Das hatten wir schon mal (gähn) und ich mag dich auch nicht. ************* A. K. schrieb: > Doch. Man kann Compiler schreiben, ohne C zu verwenden, und es müssen > keine C Compiler sein. Dann muss man von C auch keine Ahnung haben. > Allerdings würde ich, anders als er, dafür ganz sicher nicht Assembler > verwenden. ;-) Wieso? Assembler war das g*ilste was ich je programmiert habe. Vor allem in Zusammenhang mit dem zweiten Zeichensatz der Grafikkarte konnte man damit "zaubern", z.B. 255 Grafikzeichen wie Ränder von Button usw. definieren und über jedes DOS- (oder COBOL, ...)Programm eine virtuelle Grafikoberfläche legen. Die zwar kein Windows war, aber fast so aussah, und sich fast so verhielt. Mit Buttons, Popups, verschiebbaren Fenstern und allem Schnickschnack. Sogar mit Maus bedienbar, selbst wenn die zugrunde liegende Applikation keine Mausunterstützung hatte :-) Aber heute macht das vermutlich wirklich niemand mehr.
A. K. schrieb: > Eine Sprache der Bedeutung von C ist in ihrer Grundstruktur > festbetoniert. Änderungen, die in signifikantem Umfang mit bestehendem > Code brechen, wird es nicht mehr geben. Das glaub ich gern, bei Pascal und Ada ist es dabei, weil es von Anfang an mit dabei war. Allerdings hätte man bei Arduino-C schon sowas wie ein echtes Boolean implementieren können. Andererseits, wenn ich einen Mikrocontroller effizient programmieren will - nehm ich auch nicht gerade Arduino-C.
Karl schrieb: > Allerdings hätte man bei Arduino-C schon sowas wie ein echtes Boolean > implementieren können. Auch für dich: Arduino ist C++ und nicht C. Es hat den nativen Datentype _Bool im Bauch.
A. K. schrieb: > Diese Milch wurde vor zig Jahren verschüttet und du kriegst diesen Käse > nicht mehr in die Flasche zurück. C hat bestimmte Grundstrukturen. d.h. ich werfe jetzt die bools bzw. booleans raus und verwenden byte, wie ich es in C mal gelernt habe. OK. Irgendwie habe ich, back to the roots, dabei ein besseres Gefühl. Ich muss nicht mit flase und true arbeiten, das war ein Irrweg. Aber mit C ... habe ich bislang nix zu tun gehabt.
Karl schrieb: > Das glaub ich gern, bei Pascal und Ada ist es dabei, weil es von Anfang > an mit dabei war. In Pascals var p: ^boolean; zeigte also p von Anfang an auf exakt ein Bit?
Karl schrieb: > Mal ne richtige Programmiersprache: Andere, vermutlich weiter verbreitete Sprachen, >
1 | terror = bitpacked record // Errorflags |
2 | > case byte of |
3 | > 0 : (rtc, // Flag Fehler RTC |
4 | > twi, // Flag Fehler TWI |
5 | > eeprom, // Flag Fehler EEPROM |
6 | > bit3, bit4, bit5, bit6, |
7 | > sens : boolean); // Flag Fehler Sensor |
8 | > 1 : (all : uint8); |
9 | > end; |
nennen das bitfield und union > Und damit geht dann sowas: > >
1 | error.sens := true; |
2 | > ... |
3 | > if error.sens then begin |
können auch Werte zuweisen und Ausdrücke auswerten > Was kompiliert wird zu: > >
1 | lds r18,(U_sHVS_DEFINE_ss_ERROR) |
2 | > ori r18,-128 |
3 | > sts (U_sHVS_DEFINE_ss_ERROR),r18 |
4 | > ... |
5 | > lds r18,(U_sHVS_DEFINE_ss_ERROR) |
6 | > sbrs r18,7 |
7 | > rjmp .Lj343 |
8 | > oder |
9 | > lds r18,(U_sHVS_DEFINE_ss_ERROR) |
10 | > andi r18,-128 |
11 | > breq .Lj347 |
. > Besser bekommst Du das auch in Assembler nur hin, wenn Du die Flags in > einem Register hältst. und liefern eher besseren Code, weil sie es erlauben die Volatilität von Variablen zu beschreiben, um nicht jedesmal nachladen zu müssen. Aber nein, sowas geht ja nur in Assembler. Gefundene Ironie darf sofort selbst verzehrt werden.
A. K. schrieb: > In Pascals > var p: ^boolean; > zeigte also p von Anfang an auf exakt ein Bit? Nein. 8 Bit. Gab auch mal sowas wie Bytebool, Wordbool, Longbool In Pascal konnte man aber nur Wahrheitswerte zuweisen. Andere Werte führten beim Kompilieren zu Fehlermeldungen.
Roth schrieb: > A. K. schrieb: >> Diese Milch wurde vor zig Jahren verschüttet und du kriegst diesen Käse >> nicht mehr in die Flasche zurück. C hat bestimmte Grundstrukturen. > > d.h. ich werfe jetzt die bools bzw. booleans raus und verwenden byte, > wie ich es in C mal gelernt habe. OK. Irgendwie habe ich, back to the > roots, dabei ein besseres Gefühl. Ich muss nicht mit flase und true > arbeiten, das war ein Irrweg. Aber mit C ... habe ich bislang nix zu tun > gehabt. bitfields sind Teil des C-Standards, https://en.cppreference.com/w/c/language/bit_field den C++ geerbt hat und damit in der "Sprache" "Arduino" verfügbar ist. Aber das muß man nicht benutzen, nichtmal wenn man es verstanden hat.
Roth schrieb: >> In Pascals >> var p: ^boolean; >> zeigte also p von Anfang an auf exakt ein Bit? > > Nein. 8 Bit. Da fress ich einen Besen. Wirths Referenz-Implementierung von Pascal lief auf einer CDC6600 und die hat es nicht so mit 8-Bit Bytes.
:
Bearbeitet durch User
A. K. schrieb: > und die hat es nicht so mit 8-Bit Bytes. Zum Glück hat jeder C/C++ Kompiler eine Funktion eingebaut, mit der man erfragen kann wie viel Bit das jeweilige Byte hat. Obwohl... Es soll ja auch Leute geben, die meinen dass ein Byte immer 8 Bit beinhaltet. Wie sehr man sich doch irren kann....
A. K. schrieb: > In Pascals > var p: ^boolean; > zeigte also p von Anfang an auf exakt ein Bit? Bähhh, wenn ich sowas Ekliges in Pascal machen wöllte, könnte ich ja auch gleich C programmieren. ;-) Es zeigt auf ein Byte und die SizeOf von Boolean ist ein Byte. Wenn ich das in Bits will, nehme ich ein bitpacked record. Und dann zeigt der Pointer auf das Record, welches 1, 2... Bytes haben kann, je nach Anzahl der enthaltenen Booleans. Wenn ich 8 einzelne Booleans deklariere, brauchen die auch auf dem AVR 8 Byte. Wenn ich die in ein Byte haben will - siehe das Beispiel oben. Arduino Fanboy D. schrieb: > Auch für dich: Arduino ist C++ und nicht C. > Es hat den nativen Datentype _Bool im Bauch. Auch für Dich: "Each bool variable occupies one byte of memory." Nur weil die das Bool nennen, es ist trotzdem bescheiden implementiert. Ich kann je 8 Statusflags für 32 Sensoren verwenden und brauche dafür genau 32 Bytes an Speicher. Das Gleiche würde mit Arduino "Bool" 256 Bytes brauchen.
Karl schrieb: > Auch für Dich: "Each bool variable occupies one byte of memory." Welche Sprache machts besser? Liefert Zeiger auf 1 Bit? Och.. Keine... Dann geh kacken.
Apropos Pascal: In der Referenz-Implementierung konnten bei c := a + a; d := a * b; (* mit b=2 *) verschiedene Ergebnisse herauskommen. Weil die Maschine zwar 60 Bits addierte, aber nur 48 multiplizierte. Integers konnten grösser sein als maxint=2**48-1. Über die Grössen von Datentypen war in der Sprache nichts definiert, weder Wertebereich noch Platzbedarf.
:
Bearbeitet durch User
A. K. schrieb: > Über die Grössen von Datentypen war in der Sprache nichts definiert, > weder Wertebereich noch Platzbedarf. Braucht man ja auch nicht gleich beim Programmieren lernen, sondern erst wenn man reale Probleme lösen muß. Dann nimmt man was anderes ;-)
Arduino Fanboy D. schrieb: > Dann geh kacken. Ahh, sind wir wieder auf dem Niveau des Forums angelangt?
Karl schrieb: > Arduino Fanboy D. schrieb: >> Dann geh kacken. > > Ahh, sind wir wieder auf dem Niveau des Forums angelangt? Ich finde das Forum gut. Die meisten sind hilfsbereit und helfen auch gerne. Wer solche Sprüche macht, hat vermutlich "interne Gründe" ;) Arduino Fanboy D. schrieb: > Dann geh kacken. Dein Verhalten und dein Verstand ist einem Grundschüler ebenbürtig. Du scheinst in deinem Fach nicht allzuviel los zu machen.
Roth schrieb: > Du > scheinst in deinem Fach nicht allzuviel los zu machen. Ach, dafür hast du es voll auf dem Schirm! Das reicht doch für uns alle....
Arduino Fanboy D. schrieb:
(bla)
Wenn du als kleiner Student glaubst, auch später mit einer großen Klappe
durchs Leben zu kommen, dann lass dich von uns nicht aufhalten. Das
Leben wird zu deinem Feind werden.
Roth schrieb: > Wenn du mir die Doku einer Hochsprache zeigst, die fragebeantwortend > darauf eingeht, in welcher Form ein Compiler die Datenstruktur im RAM > oder Heap organisiert, kröne ich dich zum Helden im Leben der > Hochsprachen. Solche Infos findet man nicht "in der Doku", sondern nur > in (sehr speziellen) Fachbüchern zu dieser Sprache. Dann lies doch Deine Dokumente. C überlässt die Dinge größtenteils dem Compiler und dessen Handbuch beschreibt das in aller Regel detailliert. Da braucht es keine "Fachbücher".
A. K. schrieb: > Arduino Fanboy D. schrieb: >> Ein Hochsprache dient doch gerade dazu solche >> Details zu verbergen. Das ist doch Teil des >> Sinns ihrer Existenz. > > Die exakte Repräsentation von Daten kann für ein > Programm entscheidend sein. Eigentlich nicht, nein... > Wenn 2 Rechner über TCP/IP miteinander kommunizieren, ist > es nicht ganz unwichtig, dass die Repräsentation auf > beiden Seiten exakt gleich ist. ...dann sind aber mindestens ZWEI Programme beteiligt und nicht nur eins. Worauf ich mit dieser Wortklauberei hinauswill: Die konkrete Repräsentation der Daten ist immer nur dann entscheidend, wenn Daten über Programmgrenzen hinweg ausgetauscht werden müssen. Nur scheint mir dieser Aspekt merkwürdig wenig Beachtung in den üblichen Programmiersprachen zu finden -- dass es nämlich einerseits Datenobjekte gibt, die so portabel als möglich beschrieben werden müssen, weil sie über System- grenzen hinweg ausgetauscht werden, und andere, bei denen die Besonderheiten der konkreten Maschine möglichst weit- gehend ausgenutzt werden sollen, weil die Effizienz der Verarbeitung im Vordergrund steht.
lachhaft schrieb: > Wenn du als kleiner Student glaubst, Auch dir: Ein dreifach Hoch auf deinen Durchblick!
Arduino Fanboy D. schrieb: > Ach, dafür hast du es voll auf dem Schirm! > Das reicht doch für uns alle.... Lass es jetzt einfach sein! Dein Geschwurbel nervt offenbar nicht nur mich. Achim S. schrieb: > C überlässt die Dinge größtenteils dem Compiler und dessen Handbuch > beschreibt das in aller Regel detailliert. Da braucht es keine > "Fachbücher". Bis jetzt gings um Handbüchern der Sprache C. In einem Compiler Handbuch wird es natürlich drin stehen. Sowas habe ich übrigens noch nie gesehen. Braucht doch normalerweise auch niemand. Von daher "Fachbuch".
Roth schrieb: > Dein Geschwurbel nervt offenbar nicht nur > mich. Ach, etwas Schizophren heute? Der "lachhaft" das bist doch du, oder? Ich hoffe doch dass dir klar ist, dass das den Forenregeln widerspricht.
niemand schreibt um solche zeit noch.nur der einsame Student findet keinen schlaf :D
Eine erstaunlich vielfältige Diskussion für so eine scheinbar einfache Frage, wie boolean definiert ist. Um die Frage konkret zu beantworten, hilft es oft, in die Sourcen zu schauen ( der Vorteil von Open Source ). Nehmen wir als Beispiel den ESP32 Arduino Core: In der Arduino API ( also das gültige Interface für alle Arduino Implementierungen ) ist boolean folgendermaßen definiert:
1 | typedef bool boolean; |
siehe https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/Arduino.h Stellt sich also die Frage, was ist nun "bool". Dazu finden wir in http://esp32.info/docs/esp_idf/html/da/d26/xos__types_8h.html also
1 | #define bool int8_t
|
Was die Definition eines Bytes angeht ( bisher hielt ich es auch für 8Bit ) finden wir in der Wikipedia eine erstaunliche Komplexität: https://de.wikipedia.org/wiki/Byte >Zuerst mal: es gibt keine Programmiersprache namens "Arduino". Tja, eine gute Frage: was ist eine "Sprache". Der Ausdruck "die Arduino Sprache" stößt mir auch sauer auf, aber man muss genau wissen, was "Sprache" genau ist. Vielleicht können sich die studierten Informatiker zur Definition äußern.
Nachtrag: So weit ich weiß, wurde "boolean" in der Arduino-API aus Java übernommen: https://www.dpunkt.de/java/Die_Sprache_Java/Die_Sprachelemente_von_Java/26.html Der Grund ist der Versuch, die PC-Programmierung mit Processung ( Java ) https://processing.org/reference/loop_.html mit der Mikrocontroller Programmierung (C++) kompatibel zu machen. In beiden Systemen ist der Grundaufbau der Programme mit
1 | void setup() |
2 | {
|
3 | }
|
4 | void loop() |
5 | {
|
6 | }
|
kompatibel und sollen eine einheitliche Programmiersprache von PC-Steuer- und Visualisierungsprogramm bilden. Natürlich ist das auf Grund der Unterschiede zwischen Java- und C++ nur in Grenzen möglich.
chris schrieb: > aber man muss genau wissen, was > "Sprache" genau ist. Soweit mit bekannt, muss etwas, was als "echte" Computersprache durchgeht "Turing vollständig" sein. C und C++ sind das. chris schrieb: > Der Ausdruck "die Arduino > Sprache" stößt mir auch sauer auf, Mir auch... Der Begriff "Arduino Framework" gefällt mir da viel besser. Dieses Framework ist zu großen Teilen in C geschrieben. Wenige *.S Dateien, also Assembler Die *.ino, mit denen der Arduino Nutzer als erstes in Berührung kommt und viele, die meisten, der Libraries sind in C++ geschrieben. Man kann also nicht wirklich von "Der Arduino Sprache" sprechen. Aus Anwender Sicht ist es also C++, mit der Möglichkeit, auch C und Assembler einbinden zu können. ---------- Und nochmal zum Thema: Ein Bool pro Byte... Karl schrieb: > Nur weil die das Bool nennen, es ist trotzdem bescheiden implementiert. > > Ich kann je 8 Statusflags für 32 Sensoren verwenden und brauche dafür > genau 32 Bytes an Speicher. Das Gleiche würde mit Arduino "Bool" 256 > Bytes brauchen. Es ist einer der Dreh und Angel Punkte, von C und C++, dass man für jeden Datentype einen Zeiger erzeugen/nutzen kann. Das würde nicht mehr gehen, wenn sich mehrere Bool Values in einem Byte tummeln. Denn die kleinste adressierbare Einheit ist das Byte. Das ist physikalisch fest gelegt. In Hardware gegossen. Zumindest auf den AVR8 µC. Es ist also keine bescheidene Implementierung, sondern ein absolutes MUSS in C, C++ und damit auch in der Arduino Welt! Andere Prozessoren mögen sogar 16Bit, 32Bit, ... pro Bool erfordern. Natürlich mag es irgendwelche Sprachen geben, die das intern anders abhandeln... Aber diese bieten dann auch keine Zeiger.
Roth schrieb: > In einem Compiler Handbuch wird es natürlich drin stehen. Sowas habe ich > übrigens noch nie gesehen. Braucht doch normalerweise auch niemand. Von > daher "Fachbuch". OK, also wo die Tankklappe entriegelt wird, steht auch nicht in einem Buch über Autos, sondern im Handbuch. und ja, das ist sehr speziell, ...
Arduino Fanboy D. schrieb: > Aber diese bieten dann auch keine Zeiger. Mit dieser Deiner Behauptung kommt mir der Verdacht, dass Du von Obigem nichts verstanden hast. Ich schreibe für Dich nochmal ganz langsam, weil Du anscheinend nicht so schnell lesen kannst: 1. Pascal kann Pointer, auch auf Boolean Variablen. 2. Die Größe eines Boolean in Pascal kann 1 Byte, 2 Byte, 4 Byte sein, oder 1 Bit als bitpacked record, wobei der record dann wieder 1 Byte, 2 Byte... groß sein kann, je nach Anzahl der gepackten Bits. Bitpacked records sind genau das, wonach der TO gefragt hat, und werden für den AVR optimal umgesetzt.
Karl schrieb: > wonach der TO gefragt hat Du solltest Frage und Titel nochmal lesen... Dann merkst du evtl. wie weit du im Irrtum steckst. Karl schrieb: > oder 1 Bit als bitpacked record Und du willst mir jetzt erzählen, das dein Pascal, Zeiger auf einzelne Bits, in einen solchen gepackten Record erzeugt/verwaltet? Das ist dein Ernst? Wenn du dich da mal nicht irrst....
Karl schrieb: > Arduino Fanboy D. schrieb: >> Aber diese bieten dann auch keine Zeiger. > > Mit dieser Deiner Behauptung kommt mir der Verdacht, dass Du von Obigem > nichts verstanden hast. > > Ich schreibe für Dich nochmal ganz langsam, weil Du anscheinend nicht so > schnell lesen kannst: > > 1. Pascal kann Pointer, auch auf Boolean Variablen. > 2. Die Größe eines Boolean in Pascal kann 1 Byte, 2 Byte, 4 Byte sein, > oder 1 Bit als bitpacked record, wobei der record dann wieder 1 Byte, 2 > Byte... groß sein kann, je nach Anzahl der gepackten Bits. > > Bitpacked records sind genau das, wonach der TO gefragt hat, und werden > für den AVR optimal umgesetzt. Tja, und in C und C++ sind "alleinstehende" booleans auch mindestens 1 Byte groß und können wie in Pascal auch z.B. über Pointer adressiert werden. Und Pascals "bitpacked records" entsprechen dann in C bitfields. Und ebenfalls wie in Pascal lassen sich die einzelnen Bits dieses Bitfields nicht direkt ansprechen (d.h. man kann nicht einfach einen Pointer darauf erzeugen und dereferenzieren), sondern nur durch explizite Zugriffe aus das Bit im Feld (x.y). Prinzipiell also kein Unterschied zwischen diesen Sprachen was das Handling von "boolean" betrifft.
Rufus Τ. F. schrieb: > c-hater schrieb: >> Weil dieses Drecks-C schon vom Konzept her so etwas nicht vorsieht. > > Ich habe Dich schon mehrfach gebeten, Dein unsachlichen und unendlich > dümmlichen Kommentare zu unterlassen. Hast du, aber erfolglos. Einfach deshalb, weil es eben weder "unsachlich" noch "dümmlich" ist. > Weil es Dich intellektuell überfordert, zu verstehen, was C ist und was > man damit machen kann Dass ich intellektuell mit diesem Schwachsinn nicht überfordert bin, zeigen meine Kommentare. Dass hingegen du damit intellektuell überfordert bist, zeigen wiederum deine Kommentare. Du willst halt einfach nicht einsehen, dass deine bevorzugte Progammiersprache durchaus massive systematische Schwächen hat. Jede Erwähnung dieser Schwächen empfindest du als Blasphemie. Genau das ist dein Problem: Wie jeder Strenggläubige magst du keine Fakten erwähnt sehen, die deine Glaubensgrundsätze in Frage stellen. > musst Du das hier nicht in epischer Breite > überall im Forum breittreten. Doch, gerade genau das halte ich sogar für überaus nötig. Ich will nämlich keine weiteren Gäubigen wie dich, sondern lieber Wissende. Wenn du wissend wärst, hättest du mehr beitragen können als "ich will nicht, dass du das so sagst". Nämlich Fakten, die als sachliche Gegenargumente geeignet wären. Diesbezüglich war der Informationsgehalt deines Postings aber absolut exakt NULLKOMMANULL.
Arduino Fanboy D. schrieb: > Bei Arduino hapert es dann schon etwas. > Denn das ist kein C sondern eher C++. Aber das ist ihm nicht klar Das ist mir durchaus klar. Mir ist aber auch klar, dass C++ vor allem eins von C geerbt hat: Die Schwächen von C. So halt auch die Tatsache, dass es auch in C++ von Hause aus keinen boolean-Typ gibt, der nur ein Bit belegt. Es ist in C++ nur etwas leichter, einen entsprechenden Typ zu schaffen... Das wusstest du nicht? Oder willst du es, wie Rufus, bloß nicht wahrhaben? Jo mei, ihr habt zwar verschiedene "heilige Schriften", aber dasselbe Grundproblem: ihr seid Gläubige und haltet eure jeweilige Bibel für das Alleinseligmachende und mögt es nicht, wenn man Fakten erwähnt, die nicht so ganz zum Konzept passen. DAS ist dein Problem, genauso wie das von Rufus.
c-hater schrieb: > So halt auch die Tatsache, > dass es auch in C++ von Hause aus keinen boolean-Typ gibt, der nur ein > Bit belegt. Die Angelegenheit habe ich schon begründet. Aber gerne nochmal: C und auch C++ garantieren, dass man für jeden Datentype einen Zeiger bilden kann. Und das ist eben für 1 Bit breite Values nicht möglich. Denn die kleinste adressierbare Einheit, ist das Byte. Dein C Hass geht somit fachlich ins leere. Und, mit irgendwelchen Bibeln hat das nicht zu tun. Klar, könnte man Zeiger generell abschaffen...(Java,....) Aber das wäre dann kein C/C++ mehr. Wenn dir C nicht gefällt, dann kümmere dich doch nicht um C. Ignoriere es, verwende eine Sprache, welche deinen Ansprüchen gerecht wird. Du wirst C/C++, in dem Punkt, nicht mehr ändern können Die Regeln sind zementiert. Dein Hass ist also nicht mehr, als ein warmer Furz. Für dein Umfeld (hier und jetzt ich) nervig, aber machtlos und sinnlos. Tipp für dein neues Mantra: > Gott gebe mir Gelassenheit, hinzunehmen, > was nicht zu ändern ist. > Mut zu ändern, was ich ändern kann. > Und die Weisheit, zwischen beidem zu unterscheiden.
Arduino Fanboy D. schrieb: > Die Angelegenheit habe ich schon begründet. > Aber gerne nochmal: > C und auch C++ garantieren, dass man für jeden Datentype einen Zeiger > bilden kann. > Und das ist eben für 1 Bit breite Values nicht möglich. > Denn die kleinste adressierbare Einheit, ist das Byte. Ah, ja. Ein richtig schöner "Zirkular-Beweis". Weil halt C/C++ einerseits nur Zeiger auf mindestens Byte-grosse Typen vorsieht, andererseits aber garantieren will, dass für jeden Typ ein Zeiger generierbar ist, gibt's keine Bits. Die werden einfach per Sprachdefinition (=Bibel) aus der objektiven Realität getilgt. Und alles ist schick... Oder? Ich finde bei dieser Beweisführung schonmal sehr störend, dass Bits ja real nachweisbar existieren... Und ich finde eine Sprache blöd, die diese reale Existenz verleugnet, nur weil sie nicht in der Lage ist, Zeiger darauf zu verwalten. Dabei wäre es doch trivial, einen Bit-Zeiger aus einem Byte-Zeiger und einer Bitmaske/Bitnummer zusammenzusetzen. Und tatsächlich ist das ja wohl genau das, was einschlägige (C/C++) Bibliotheken für bestimmte Zielsysteme dann tasächlich tun. Es geht also durchaus. Die Frage ist also: warum kann die Sprache selber das nicht von Hause aus? Und die einzig mögliche Antwort ist: weil sie SCHEISSE ist.
Ich finde diese Diskussion recht merkwürdig. Die Register heutiger CPUs haben eine Breite von 32 oder auch 64Bit, je nach CPU und deren Mode, in dem sie arbeitet. Ob ich nun mit einer Information von einem oder 32Bit arbeite ist vollkommen egal - es werden mindestens 4Byte verarbeitet, auf den Stack geschoben usw. wenn ich nun in C Bitfelder brauche, dann mache ich sie mir selbst und idealerweise in einem Datentyp der für der vorzeichenlos ist und Registerbreite hat - wo ist da jetzt eigentlich das Problem?
Walter K. schrieb: > Ich finde diese Diskussion recht merkwürdig. Ich auch -- aber schätzungsweise aus ganz anderen Gründen :) > Die Register heutiger CPUs haben eine Breite von 32 > oder auch 64Bit, je nach CPU und deren Mode, in dem > sie arbeitet. Zumindest ein klassischer MSP430 hat keine 32-Bit-Register, 64 Bit schon gar nicht -- und der ist sehr "heutig". > Ob ich nun mit einer Information von einem oder 32Bit > arbeite ist vollkommen egal - es werden mindestens > 4Byte verarbeitet, auf den Stack geschoben usw. Nicht allen Leute ist der Ressourcenverbrauch völlig egal. Ich bastele zeitweise an speziellem Bildverarbeitungszeug für Binärbilder. Dort können Zwischenbilder in der Größen- ordnung von Gigapixeln anfallen. Da ich gern erreichen würde, dass der Kram auch künftig noch auf 32-Bit-Systemen läuft, ist es ÜBERHAUPT nicht egal, ob ein Pixel ein Bit oder vier Byte in Anspruch nimmt. Davon hängt nämlich ab, ob 1 Gigapixel im Speicher 4GByte belegt oder nur 128MByte. > wenn ich nun in C Bitfelder brauche, dann mache ich sie > mir selbst und idealerweise in einem Datentyp der für > der vorzeichenlos ist und Registerbreite hat - wo ist > da jetzt eigentlich das Problem? Falsche Frage. Wozu bietet C Bitfelder an, wenn man in der Praxis nix damit anfangen kann? Man verwendet ja nicht deshalb einen Compiler, damit man die Basiskonstrukte dann DOCH von Hand stricken muss. Das ist irgendwie sinnfrei.
Egon D. schrieb: > Falsche Frage. Wozu bietet C Bitfelder an, wenn man > in der Praxis nix damit anfangen kann? Man verwendet > ja nicht deshalb einen Compiler, damit man die > Basiskonstrukte dann DOCH von Hand stricken muss. Das > ist irgendwie sinnfrei. Blasphemie! Auf den Scheiterhaufen mit dem Ketzer!
Egon D. schrieb: > Falsche Frage. Wozu bietet C Bitfelder an, wenn man > in der Praxis nix damit anfangen kann? Aber nicht doch. Man kann etwas damit anfangen. Aber nicht immer das, was man damit gerne anfangen würde. Das ist wie bei einem kleinen Kind. Das Spielzeug taugt nicht dazu, was es damit grade machen wollte. Also kriegt es einen Wutanfall und trampelt auf dem Spielzeug herum.
Egon D. schrieb: > Ich bastele zeitweise an speziellem Bildverarbeitungszeug > für Binärbilder. Dort können Zwischenbilder in der Größen- > ordnung von Gigapixeln anfallen. Wie helfen Dir dabei Bit-Variablen (wenn es sie gäbe)? Enthält dein Programm Milliarden Variablen? Oder enthält es nicht eher wie üblich Arrays von (z.B.) 32bit Werten, wo jedes einzelne Bit einem Pixel entspricht?
Egon D. schrieb: > Wozu bietet C Bitfelder an, wenn man > in der Praxis nix damit anfangen kann? Bitfelder sind in C durchaus nützlich und sinnvoll. Sie sind genau dann problematisch, wenn sie mit anderen Datentypen interagieren müssen, durch "union", "struct" oder Zeiger. Im Übrigen hat zumindest der SDCC für manche Architekturen eine spezifische Optimierung von "bool", um hardwareseitig vorhandene Einzelbitregister sinnvoll nutzen zu können. Solch ein bool belegt real dann tatsächlich nur ein Bit.
Egon D. schrieb: >> Die Register heutiger CPUs haben eine Breite von 32 >> oder auch 64Bit, je nach CPU und deren Mode, in dem >> sie arbeitet. > > Zumindest ein klassischer MSP430 hat keine 32-Bit-Register, > 64 Bit schon gar nicht -- und der ist sehr "heutig". das war ja klar, dass nun ein super Schlauer kommt - und drauf aufmerksam macht, dass es noch 16Bit CPUs gibt. Hätte ich diese auch erwähnt, käme der Hinweis auf 8Bit ;-)
S. R. schrieb: > Im Übrigen hat zumindest der SDCC für manche Architekturen eine > spezifische Optimierung von "bool", um hardwareseitig vorhandene > Einzelbitregister sinnvoll nutzen zu können. Solch ein bool belegt real > dann tatsächlich nur ein Bit. Ja, klar, und dieser Kram ist dann genauso portabel wie Assemblercode. Damit ist jegliches Argument für die Verwendung von C ganz unmittelbar vom Tisch...
Egon D. schrieb: > Da ich gern erreichen würde, dass der Kram auch künftig > noch auf 32-Bit-Systemen läuft, ist es ÜBERHAUPT nicht > egal, ob ein Pixel ein Bit oder vier Byte in Anspruch > nimmt. Und Du glaubst nun wirklich, in C für jedes Pixel 4 Byte nehmen zu müssen?
c-hater schrieb: > Ja, klar, und dieser Kram ist dann genauso portabel wie Assemblercode. Du zeigst deine Kompetenz mal wieder von der besten Seite. Es handelt sich um C-Code und einen optimierenden Compiler. > Damit ist jegliches Argument für die Verwendung > von C ganz unmittelbar vom Tisch... "as-if"-Regel sagt dir was, ja?
Walter K. schrieb: > Egon D. schrieb: >>> Die Register heutiger CPUs haben eine Breite von 32 >>> oder auch 64Bit, je nach CPU und deren Mode, in dem >>> sie arbeitet. >> >> Zumindest ein klassischer MSP430 hat keine 32-Bit-Register, >> 64 Bit schon gar nicht -- und der ist sehr "heutig". > > das war ja klar, dass nun ein super Schlauer kommt - und drauf > aufmerksam macht, dass es noch 16Bit CPUs gibt. > Hätte ich diese auch erwähnt, käme der Hinweis auf 8Bit ;-) Und zwar zu Recht, denn es geht hier um Arduino (siehe Überschrift), was sich in der Regel auf einen AVR bezieht, der eben ein 8-Bit-Prozessor ist. Dementsprechend ist eher der Hinweis auf 64-Bit-Prozessoren in dem Kontext etwas merkwürdig. Welche 64-Bit-Arduinos kennst du?
Rolf M. schrieb: > Walter K. schrieb: >> das war ja klar, dass nun ein super Schlauer kommt - und drauf >> aufmerksam macht, dass es noch 16Bit CPUs gibt. >> Hätte ich diese auch erwähnt, käme der Hinweis auf 8Bit ;-) > Und zwar zu Recht, denn es geht hier um Arduino (siehe Überschrift), was > sich in der Regel auf einen AVR bezieht, der eben ein 8-Bit-Prozessor > ist. Das Problem ist nicht das Target. Das kann, was es halt kann. Das Problem ist die Sprache, die nicht angemessen unterstützt, was das Target kann. Nur Assembler unterstützt alles, was das Target kann. Allerdings eben leider nur für das Target, allenfalls für eine Familie ähnlicher Targets. Der Kernpunkt ist: C/C++ ist NICHT die Lösung für alles. Eben weil diese Sprachen massive Einschränkungen haben, teilweise sogar ziemlich sinnlose, allein aus der Historie dieser Dinosauerier gewachsene... Das Thema Bitzugriffe ist so ein Ding. Prinzipiell durchaus auf Sprachebene lösbar, das würde aber erheblichen Aufwand in den Compilern und deren Codegeneratoren verursachen. Und entweder die Kompatibilität mit unzähligen existierenden Anwendungen brechen oder unsäglich langsam ein. Deswegen wird's halt nicht gemacht. Und deswegen ist C/C++ SCHEISSE. Zeugs von vorgestern halt...
c-hater schrieb: sinnvolles Zuegs und dann das: > Und deswegen ist C/C++ SCHEISSE. Du kannst es nicht lassen. Dein Benehmen ist sch......lecht. Es wäre wirklich angebracht, dass du lernst, dich gepflegt auszudrücken. Im übrigen ist deine Meinung du C/C++ nicht allgemein gültig. Deine Ausdrucksweise vernichtet darüber hinaus jede Chance, ernst genommen zu werden. Wenn du es ordentlich formulieren würdest, würden Dir 50x mehr Leute folgen. Aber so ziehst du nur das unterste Kroppzeug an.
Walter K. schrieb: > wo ist da jetzt eigentlich das Problem? Nun, offenbar besteht das Problem darin, dass Dir entgangen ist, dass es um Arduino geht. Arduino Fanboy D. schrieb: > Und du willst mir jetzt erzählen, das dein Pascal, Zeiger auf einzelne > Bits, in einen solchen gepackten Record erzeugt/verwaltet? Soll ichs nochmal gaaaanz langsam schreiben? Der Pointer zeigt auf die Adresse des das bitpacked record enthaltende Byte, Word oder Longword. Auch wenn es Dir schwerfällt es zu verstehen: Pascal ist eine Hochsprache, da ist dieses Rumgepointere, wie Du es von C kennst zwar möglich, aber selten nötig. Das Einzige, wofür ich Pointer in Pascal für AVR verwende ist, um Daten aus dem Progmem zu lesen. Ralf D. schrieb: > Und Pascals "bitpacked records" entsprechen dann in C bitfields. Dann wäre "bitfields" genau die richtige Antwort auf die Frage des TO zum platzsparenden Speichern von Flags gewesen. Und warum schafft es Herr Carl D., der das oben schon angebracht hat, oder ein anderer der C(++)-Fans nicht, da mal ein Beispiel zu bringen, um den TO zu zeigen, wie es gehen könnte? Isses nicht praktikabel in C, oder wirds vom Compiler nicht praktikabel umgesetzt, oder isses geheimes Wissen, welches nur in eingeweihten Druidenzirkeln von Mund zu Ohr weitergegeben werden darf? > sondern nur durch explizite > Zugriffe aus das Bit im Feld (x.y). Was, wie obiges Beispiel zeigt, vom Compiler optimal umgesetzt wird, es gibt also keinen Grund das nicht zu nutzen.
Stefanus F. schrieb: > Egon D. schrieb: > >> Ich bastele zeitweise an speziellem Bildverarbeitungszeug >> für Binärbilder. Dort können Zwischenbilder in der Größen- >> ordnung von Gigapixeln anfallen. > > Wie helfen Dir dabei Bit-Variablen (wenn es sie gäbe)? Ich könnte ein Array aus z.B. 32k x 32k Bitvariablen anlegen (welches im Speicher dann z.B. nur 128MByte kosten würde). Das geht aber nicht so einfach; das muss man alles zu Fuß lösen. > Enthält dein Programm Milliarden Variablen? Nicht als individuell benannte Steuervariablen, natürlich. Aber Feldelemente sind für mich auch Variablen. Und das Problem hat noch eine andere Dimension: Aus algorithmischen Gründen will ich eigentlich nicht nur ein Array aus binären Variablen haben, sondern eine Liste, deren Länge in weiten Grenzen veränderlich ist. Dafür gibt es in keiner Form Unterstützung, weder in Pascal noch in C. > Oder enthält es nicht eher wie üblich Arrays von (z.B.) > 32bit Werten, wo jedes einzelne Bit einem Pixel entspricht? Klar ist das so -- aber das ändert am Kernproblem letztlich nix: Die Maschine beherrscht intern alle booleschen Operationen, stellt mir aber keinen vernünftigen Datentyp dafür zu Verfügung.
Egon D. schrieb: > Die Maschine beherrscht intern alle booleschen Operationen Nein, tut sie nicht. Die kann vielleicht mit Bitadressen in den speziellen Registern der CPU umgehen. Aber mehr auch nicht. Bei deinen Datenmengen reden wir aber von RAM. Das sind die Dinger, die man als Riegel ins PC-Board steckt. Und die sind nicht bitadressierbar. Da kann dir irgendeine noch so tolle Sprache anbieten, was sie will. Am Ende läuft es immer auf das selbe hinaus: Byte lesen, maskieren, Bit in die passende Position schieben. Und da führt kein Weg dran vorbei. Sieh es mal so: C(++) ist wenigstens so ehrlich und sagt dir: Gibt es nicht. Und gaukelt dir nicht irgendeine Pseudoperformance vor.
Egon D. schrieb: > Aus > algorithmischen Gründen will ich eigentlich nicht nur > ein Array aus binären Variablen haben, sondern eine > Liste, deren Länge in weiten Grenzen veränderlich ist. Dir ist aber schon bewußt, dass der Witz bei einem Array ist, dass sich jede Adresse (und Subadresse, sprich das Bit in einem Array vom Typ bitpacked record) berechnen läßt, während eine Liste zu jedem Listeneintrag einen Index braucht, da ja auch Elemente in der Liste beliebig gelöscht werden können. Üblicherweise wird der Vorgänger und der Nachfolger in der Liste gespeichert. Wenn Du eine Liste aus Bits machen wölltest, würde die Listenverwaltung deutlich mehr Platz beanspruchen als die Listenelemente (Deine Bits) selbst.
Thomas E. schrieb: > Egon D. schrieb: >> Die Maschine beherrscht intern alle booleschen >> Operationen > > Nein, tut sie nicht. ??? Für NOT, AND, OR, XOR gibt's praktisch immer direkt Maschinenbefehle, und zwar auch noch parallel mit Registerbreite. Selbst ein 8-Bit-Prozessor ist eine 8fach parallele Bit-Vektor-Maschine. > Bei deinen Datenmengen reden wir aber von RAM. Das sind > die Dinger, die man als Riegel ins PC-Board steckt. > Und die sind nicht bitadressierbar. Das habe ich auch nicht behauptet. Bitadressierbarkeit und boolesche Operationen sind zwei Paar Schuhe. > Da kann dir irgendeine noch so tolle Sprache anbieten, > was sie will. Am Ende läuft es immer auf das selbe > hinaus: Byte lesen, maskieren, Bit in die passende > Position schieben. Und da führt kein Weg dran vorbei. Das ist nur bei bitweisem I/O so. Die interne Verarbeitung kann man oft genug mit voller Registerbreite machen. Um z.B. zu bestimmen, welche Bits sich geändert haben, berechne ich nur "Vektor_alt XOR Vektor_neu". Das läuft auf einem 32Bit-Rechner 32fach parallel. > Sieh es mal so: C(++) ist wenigstens so ehrlich und > sagt dir: Gibt es nicht. Und gaukelt dir nicht > irgendeine Pseudoperformance vor. Klar. Deshalb kann man ja auf einem AVR auch keine Fließkommazahlen verwenden. Der Compiler gaukelt da keine Pseudoperformance vor ;)
Karl schrieb: > Egon D. schrieb: >> Aus algorithmischen Gründen will ich eigentlich >> nicht nur ein Array aus binären Variablen haben, >> sondern eine Liste, deren Länge in weiten Grenzen >> veränderlich ist. > > Dir ist aber schon bewußt, dass der Witz bei einem > Array ist, dass sich jede Adresse (und Subadresse, > sprich das Bit in einem Array vom Typ bitpacked > record) berechnen läßt, während eine Liste zu > jedem Listeneintrag einen Index braucht, da ja > auch Elemente in der Liste beliebig gelöscht werden > können. Das ist viel weniger ein Gegensatz, als Du denkst. Wenn die Listenelemente alle gleich groß sind, kann man auch die Adresse jedes Listenelementes explizit berechnen. Eine Liste kann aber ihre Länge dynamisch ändern, was bei Arrays nicht immer geht. > Üblicherweise wird der Vorgänger und der Nachfolger > in der Liste gespeichert. Das ist das, was im Informatikunterricht gelehrt wird :) Man MUSS das ja aber nicht so machen. Von Listen in Tcl weiss ich, dass man dort mittels Index explizit auf bestimmte Elemente zugreifen kann, und das funktioniert auch mit brauchbarer Geschwindigkeit. Ich vermute (!), dass die Tcl-Listen irgendwie auf Basis von Bäumen implementiert sind. > Wenn Du eine Liste aus Bits machen wölltest, würde die > Listenverwaltung deutlich mehr Platz beanspruchen als > die Listenelemente (Deine Bits) selbst. Die Gefahr besteht -- aber das hilft nichts. Bildverarbeitung und -erkennung hat häufig mit Segmentierung zu tun, d.h. mit Zerlegung eines Bildes in Teilbilder nach inhaltlichen Kriterien. Das lässt sich auf der Basis von klassischen Arrays allein nicht sinnvoll implementieren.
Egon D. schrieb: > Eine Liste kann aber ihre Länge dynamisch ändern, was > bei Arrays nicht immer geht. http://wiki.freepascal.org/Array/de#Dynamisches_eindimensionales_Array_.28.3DArray_mit_ver.C3.A4nderlicher_Gr.C3.B6.C3.9Fe.29 Egon D. schrieb: > dass man dort mittels Index > explizit auf bestimmte Elemente zugreifen kann Je schneller man mit der Liste arbeiten will, desto mehr Infos muss man speichern. Will man schnell Elemente löschen oder sortieren, braucht man Vorgänger und Nachfolger, egal ob linear oder im Baum. Will man schnell auf ein Element zugreifen, braucht man einen Index. Egon D. schrieb: > mit Zerlegung eines Bildes > in Teilbilder nach inhaltlichen Kriterien. Das lässt > sich auf der Basis von klassischen Arrays allein nicht > sinnvoll implementieren. Da werd ich Dir nix Neues erzählen: Bild erweitern auf passende Vielfache z.B. von 8, und beim Zerlegen in Teilbilder entsprechend die Koords der Ecken abspeichern.
Walter K. schrieb: > Egon D. schrieb: >> Da ich gern erreichen würde, dass der Kram auch >> künftig noch auf 32-Bit-Systemen läuft, ist es >> ÜBERHAUPT nicht egal, ob ein Pixel ein Bit oder >> vier Byte in Anspruch nimmt. > > Und Du glaubst nun wirklich, in C für jedes Pixel > 4 Byte nehmen zu müssen? Natürlich nicht -- aber welche Rolle spielt das? Hier wurde so getan, als ob man ja sowieso nur höchstens ein paar Dutzend boolesche Variablen benötigt, so dass der Speicherbedarf völlig egal ist. Dem habe ich widersprochen: Es gibt sehr wohl Anwendungen, die auf "Numerik" mit SEHR großen Mengen boolescher Variablen beruhen -- nur ist die Unterstützung dessen durch Hochsprachen recht inkonsequent. Die Basisoperationen NOT, AND, XOR usw. stehen meist zur Verfügung, aber mit den Datentypen hapert es.
S. R. schrieb: > Egon D. schrieb: >> Wozu bietet C Bitfelder an, wenn man >> in der Praxis nix damit anfangen kann? > > Bitfelder sind in C durchaus nützlich und sinnvoll. "Unkraut sind Pflanzen, deren Vorzüge noch nicht erkannt wurden." :) Mag sein, dass es nützliche Anwendungen dafür gibt -- ich bin offenbar nicht geübt darin, sie zu erkennen. > Sie sind genau dann problematisch, wenn sie mit > anderen Datentypen interagieren müssen, durch "union", > "struct" oder Zeiger. Naja, leider ist das der Normalfall, wenn man sich nicht nur ein paar Ergebnisse früherer Entscheidungen merken will, sondern richtige "binäre Numerik" braucht. > Im Übrigen hat zumindest der SDCC für manche > Architekturen eine spezifische Optimierung von "bool", > um hardwareseitig vorhandene Einzelbitregister sinnvoll > nutzen zu können. Solch ein bool belegt real dann > tatsächlich nur ein Bit. Ich sehe das Problem eher in dem äußerst rudimentären Typsystem. Wenn die Kiste 32bit lange Binärvektoren mit einem Rutsch verarbeitet, ist das ja in vielen Fällen durchaus charmant -- nur kann man die zugehörige Daten- struktur nicht mit zivilen Mitteln ausdrücken. Das läuft dann immer auf unsigned long oder soetwas hinaus. Das Bitgefummel und die Speicherverwaltung macht man dann komplett zu Fuß.
Egon D. schrieb: > Es gibt sehr wohl Anwendungen, die auf "Numerik" mit SEHR großen Mengen > boolescher Variablen beruhen -- nur ist die Unterstützung dessen durch > Hochsprachen recht inkonsequent. Die Basisoperationen NOT, AND, XOR usw. > stehen meist zur Verfügung, aber mit den Datentypen hapert es. Dann mach doch Mal ein Beispiel, was Du gerne hättest. Gerade Bit Manipulationen sind doch in C täglich Brot und flexibel nachbildbar. Nicht immer optimal portabel in einem Rutsch, aber hey, dann gibt's eben 4 * 10 Zeilen Code für die 4 Bitbreiten und das meinetwegen noch für jede Endianess.
Achim S. schrieb: > Dann mach doch Mal ein Beispiel, was Du gerne hättest. Naja, ein zweidimensionales Array mit 1024x1024 booleschen Variablen, das tatsächlich nur 128kByte belegt, wäre schon ganz nett. Geht aber nicht -- weil es nichtmal einen anständigen booleschen Datentyp gibt. > Gerade Bit Manipulationen sind doch in C täglich Brot > und flexibel nachbildbar. Sicher -- indem man "unsigned int" o.ä. als Container verwendet. Das sage ich doch die ganze Zeit: Die OPERATIONEN sind alle da, nur die Datentypen sind ein Krampf.
Egon D. schrieb: > Naja, ein zweidimensionales Array mit 1024x1024 booleschen > Variablen, das tatsächlich nur 128kByte belegt, wäre schon > ganz nett. Falls Du die Transformation x,y => pos noch selbst hinbekommst: https://www.freepascal.org/docs-html/rtl/classes/tbits.html
1 | program tbittest; |
2 | |
3 | uses |
4 | classes; |
5 | |
6 | const |
7 | xs = 1024; |
8 | ys = 1024; |
9 | |
10 | var |
11 | bits : TBits; |
12 | x, y : longint; |
13 | |
14 | begin |
15 | bits := TBits.Create(); |
16 | bits.Size := xs * ys; |
17 | |
18 | WriteLn('Anzahl: ', bits.Size); |
19 | WriteLn('Records: ', bits.GetFSize); // Anzahl verwendeter Records |
20 | WriteLn('Bytes: ', SizeOf(bits)); // Länge eines Records in Byte |
21 | WriteLn('Größe: ', bits.GetFSize * SizeOf(bits)); |
22 | |
23 | for x := 0 to xs - 1 do begin |
24 | y := x; |
25 | bits.SetOn(x * xs + y); // Diagonale |
26 | end; |
27 | |
28 | WriteLn('Erstes: ', bits.Get(0)); |
29 | WriteLn('Zweites: ', bits.Get(1)); |
30 | WriteLn('Letztes: ', bits.Get(xs * ys - 1)); |
31 | |
32 | ReadLn(); |
33 | bits.Free; |
34 | end. |
Benötigt bei mir 256kByte, möglicherweise weil 64 Bit System. Performance musst Du selbst testen.
Thomas E. schrieb: > Sieh es mal so: C(++) ist wenigstens so ehrlich und sagt dir: Gibt es > nicht. Und gaukelt dir nicht irgendeine Pseudoperformance vor. Yep. C/C++ liefern eine ziemlich direkte Abbildung der Situation vieler Rechnerarchitekturen, ohne ausgeprägte Abstraktion. Wobei sich das aber auf die Sicht des Programmierers auf die Architektur bezieht, nicht notwendigerweise auf die reale Hardware. Dazu passt auch das Fehlen von Strings als nativem skalerem Datenobjekt. > Bei deinen Datenmengen reden wir aber von RAM. Das sind die Dinger, die > man als Riegel ins PC-Board steckt. Und die sind nicht bitadressierbar. Das ist kein zwingendes Kriterium, denn die Byteadressierbarkeit ist bei PC-Speicher aus Sicht des Prozessors eher ein historisches Relikt als gelebte Praxis. Byteoperationen tauchen allenfalls noch in DMA auf, und wenn non-cachable oder write through. Mit ECC-RAM verschwinden auf dem Speicherbus schreibende Operationen unterhalb der entsprechenden Wortbreite des Speichers völlig. So kann es Bytes als adressierbare Datentypen geben, selbst wenn der Speicherbus keine Bytes implementiert. TIs 9900 Prozessor (=> TI 99/4A Rechner der C64-Ära) adressierte zwar im Daten/Programmbereich Bytes, der Bus führte aber keine Bytezugriffe durch. Das sah man als Programmierer jedoch nicht. Befehle, die Bytes schrieben, wickelten das über Wortzugriffe und read-modify-write ab. Das war also recht genau das gleiche Verfahren auf Byteebene, das die meisten Cortex M Cores auf Bitebene implementieren. Über Bitbanding sind einzelne Bits aus Sicht des Programmierers getrennte und individuell adressierbare Daten, obwohl das Speichersystem das nicht widerspiegelt. Weil auch hier über read-modify-write geschrieben wird. Wenn man kleine Mikrocontroller und I/O-Spaces verlässt und Datenoperationen über write-allocate Caches betrachtet, ist der RAM-Zugriff ohnehin völlig von den Befehlsoperationen losgelöst, da dabei im (cachable) RAM nurmehr blockweise gelesen und geschrieben wird und zwischen Bytes/Maschinenworten und der Breite des Speicherbusses jeder Zusammenhang verloren geht. NB: Ebendiese TI-990 Architektur hatte einen zweiten I/O-Bus, der tatsächlich bitweise adressierte und mit 1 Bit Breite arbeitete, ohne read-modify-write. Die Bits in I/O-Registern waren individuelle Einheiten und ein Transferregister einer UART war kein Byte oder Wort, sondern ein Bitarray. I/O-Befehle des Prozessors jenseits von Einzelbits waren Blocktransfers für 1-16 Bits. In C ist das nicht direkt abbildbar.
:
Bearbeitet durch User
A. K. schrieb: > Thomas E. schrieb: > Yep. C/C++ liefern eine ziemlich direkte Abbildung der Situation vieler > Rechnerarchitekturen, ohne ausgeprägte Abstraktion. > Dazu passt auch das Fehlen von > Strings als nativem skalerem Datenobjekt. hmm, c++ hat keine Strings als natives skalares Datenobkekt? Was bedeutet das? Darf man die Implementierung nicht sehen können? Darf kein buchstabenweiser Zugriff existieren? Viele liebe Grüße Timm
Timm R. schrieb: > hmm, c++ hat keine Strings als natives skalares Datenobkekt? Damit meinte ich Grunddatentypen wie char, int, double, enum. Die nicht innerhalb der Sprache von Grunddatentypen abgeleitet sind. Mit denen du direkt arbeiten kannst, ohne sie selbst implementieren zu müssen, oder auf eine explizite Library zurückgreifen zu müssen. Mag sein, dass der Begriff "skalar" auf Strings in Perl, PL/I, BASIC etwas arg gedehnt ist, aber in diesem Sprachen sind Strings Grunddatentypen, keine Arrays, keine Structs, etc. In C++ ist std::string eine normale Klasse, ein abgeleiteter Typ, dessen Existenz bereits in der Sprachreferenz gefordert wird. Die Objekte betten sich dank operator overloading lediglich optisch ähnlich zu Grunddatentypen ein. Es gibt auch in C++ z.B. keine lexikalischen std::string Objekte. Zurück zu dem, worum es hier geht: C definiert in diesem Sinn nur solche Datentypen als Grunddatentypen, die von Hardware oft ziemlich direkt als individuelle und voneinander unabhängige Elemente unterstützt werden, ohne auf mehr oder weniger komplexe Software-Implementierung zurückgreifen zu müssen. Das ist bei Strings nicht der Fall. Da C++ ist diesem Sprachteil direkt an C angelehnt ist, ist das auch nicht anders. Einzelne Bits passen in den meisten Architekturen nicht in das Schema der anderen Datentypen. Und sowas wie Bitarrays in Pascal, also packed array of boolean, lassen sich in C/C++ mit Sprachmitteln selbst implementieren, so dass man - deren Sprachphilosophien folgend - das nicht in den Sprachkern einbauen muss.
:
Bearbeitet durch User
Karl schrieb im Beitrag #5593952. > > Dann wäre "bitfields" genau die richtige Antwort auf die Frage des TO > zum platzsparenden Speichern von Flags gewesen. > > Und warum schafft es Herr Carl D., der das oben schon angebracht hat, > oder ein anderer der C(++)-Fans nicht, da mal ein Beispiel zu bringen, > um den TO zu zeigen, wie es gehen könnte? Der mit "C" im Namen hat das weiter oben längst gemacht, nur scheint der mit "K" im Namen den dort zu findende Sourcecode nicht als solchen wahrzunehmen. Ein Tip, es ist der Text mit den geschweiften Klammer drin.
Beitrag #5594123 wurde von einem Moderator gelöscht.
Karl schrieb:
[ein Pascal Programm, das Bit-Arrays in Pascal demonstriert]
ein wenig erscheint mir die Diskussion, als ob man sich bei einem
Formel-1 Wagen über die fehlende Einparkautomatik und über die fehlenden
Iosfix Sockel beschwert.
Es hat nie jemand behauptet, dass C eine ideale Sprache für den
Schulunterricht ist. Ich finde auch die Kriterien, die hier teilweise
angelegt werden, damit eine Sprache kein Schei*sprache ist, ziemlich
schräg und willkürlich. C ist halt maschinennah, ohne Servolenkung, ohne
Iosofix und ohne Wurzelholzkonsolen.
Zum Thema: Wenn ich denn partout ein bitweises Array haben will, dann
muss ich halt
1 | bit_setzen(int array[], int index) {array[(index/32)] |= (1 << (index%32));} |
2 | bit_loeschen(int array[], int index) {array[(index/32)] &= ~(1 << (index%32));} |
3 | int bit_lesen(int array[], int index) {return array[(index/32)] & (1 << (index%32)); ) |
oder so ähnlich (nicht getestet, sorry) schreiben. Wow! Das kostet einen ja glatt Jahre Lebenszeit. Dafür kann ich es dann auf den konkret gewünschten Fall genau anpassen, zum Beispiel auch char nehmen, oder natürlich auch unsigned int :-), oder die 32 noch durch sizeof veredeln :-) Verlieren tut man garnichts, denn auch die Pascal-Version kann nicht zaubern, sondern tut genau das selbe, nur nicht anpassbar und transparent. > Benötigt bei mir 256kByte, möglicherweise weil 64 Bit System. Dafür würde die Version s.o. eben dann auch nur 128 kByte verbrauchen und man wüsste warum. > Performance musst Du selbst testen. Der Fall, dass man in so einem bit-Array wirklich nur in jedem 32 oder 64 Bit Bereich genau ein Bit schreiben will, ist doch extrem exotisch. In der handgestrikten Variante kann ich aber jederzeit immer noch mit bus-breiten Masken drüber ackern, eine Freiheit, die ich bei der Pascal Version nicht habe. Die C-Version ist immer mindestens genau so schnell wird aber für die meisten Algorithmen die Möglichkeit bieten deutlich schneller zu sein. Die Pascal-Variante löst ein Problem, dass in der Version (Zugriff auf immer höchstens ein Bit pro Busbreite) nicht existiert, ist real immer ineffizienter und deswegen zwar didaktisch wertvoll, aber doch rein akademisch. vlg Timm
Timm R. schrieb: > Der Fall, dass man in so einem bit-Array wirklich nur in jedem 32 oder > 64 Bit Bereich genau ein Bit schreiben will, ist doch extrem exotisch. Du hast aber schon gesehen, dass es für TBits auch Xor, Or, And gibt, mit dem man einen Teil oder den kompletten Bitsatz bearbeiten kann? Timm R. schrieb: > Die Pascal-Variante löst ein Problem, dass in der Version (Zugriff auf > immer höchstens ein Bit pro Busbreite) nicht existiert... Bereitet es Dir persönlich Schmerzen, dass eine Hochsprache eine elegante Lösung bietet, für die Du mit Deinem Makroassembler erst irgendwelche Konstrukte erfinden musst?
In jeder (Programmier-) Sprache gibt es schöne und weniger schöne Eigenschaften. Ich bleibe bei deutsch, weil das meine Muttersprache ist. Ich wechsle nicht komplett zu französisch, weil man damit schöner singen kann. Ich wechsle nicht zu niederländisch, weil dort die Rechtschreibung einfacher ist. Ich wechsle nicht komplett zu englisch, weil es internationaler ist. Deutsch ist gewiss nicht die schönste/beste/einfachste/verbreitetste Sprache und doch spreche ich deutsch und niemand beschimpft mich dafür. Können wir das bei den Programmiersprachen nicht ebenso handhaben?
Karl schrieb: > Timm R. schrieb: >> Der Fall, dass man in so einem bit-Array wirklich nur in jedem 32 oder >> 64 Bit Bereich genau ein Bit schreiben will, ist doch extrem exotisch. > > Du hast aber schon gesehen, dass es für TBits auch Xor, Or, And gibt, > mit dem man einen Teil oder den kompletten Bitsatz bearbeiten kann? Also so wie:
1 | var bits1, bits2: TBits; |
2 | begin |
3 | bits1 := (bit1, bit5); |
4 | bits2 := (bit3, bit5); |
5 | bits1 Xor:= bits2; |
6 | end; |
Bitte zeigen! > Timm R. schrieb: >> Die Pascal-Variante löst ein Problem, dass in der Version (Zugriff auf >> immer höchstens ein Bit pro Busbreite) nicht existiert... > > Bereitet es Dir persönlich Schmerzen, dass eine Hochsprache eine > elegante Lösung bietet, für die Du mit Deinem Makroassembler erst > irgendwelche Konstrukte erfinden musst? Da es ja offenbar um "ObjectPascal" geht, bitte auch mit der richtigen C-Version vergleichen. Da muß man nicht jeden Operator mit Methodenaufrufen simulieren, "they left that TO Java".
C wurde entwickelt, um auf kleinen Rechnern mit wenig RAM verwendet werden zu können, ohne dafür zig Durchläufe zu verwenden. Das prägte die Sprache. Was in C selbst implementiert werden kann, ohne dabei viel zu verlieren, blieb folglich draussen. Eine andere Sprache aus der gleichen Ära ist beispielsweise PL/I. Die war als Ablösung von FORTRAN und COBOL vorgesehen und hat einen höheren Abstraktionsgrad, wenig orientiert an realer Hardware. Zur Implementierung: "To fit a large compiler into the 44 kilobytes of memory available on a 64-kilobyte machine, the compiler consists of a control phase and a large number of compiler phases (approaching 100)." Bezeichnenderweise war PL/I die Sprache des Betriebsystems Multics, dessen Grösse und Aufwand direkt in die Entwicklung des kleinen Unix mündete, mit C als Sprache. Das wirkte bis in die 80er nach, aber heute sind diese damaligen Beschränkungen und Aufwände lächerlich. Die Grundlage von C war dadurch aber gelegt und wirkt bis heute nach. Die Philosophie blieb erhalten, auch in C++: Was in der Sprache selbst implementiert werden kann, ohne dabei viel zu verlieren, bleibt draussen und landet in Libraries. Als Klasse implementierte Bitarrays in C++ verlieren kaum etwas gegenüber einer Implementierung im Sprachkern. Diese Philosophie muss nicht jedem gefallen. Aber jeder, der C oder C++ verwendet, muss damit leben. Oder, wenn er unbedingt eigene Erweiterungen braucht, eben selber implementieren (BTDT).
:
Bearbeitet durch User
Hallo Karl, Karl schrieb: > Timm R. schrieb: >> Der Fall, dass man in so einem bit-Array wirklich nur in jedem 32 oder >> 64 Bit Bereich genau ein Bit schreiben will, ist doch extrem exotisch. > > Du hast aber schon gesehen, dass es für TBits auch Xor, Or, And gibt, > mit dem man einen Teil oder den kompletten Bitsatz bearbeiten kann? ok, das wäre natürlich dann schon sehr nice! Hättest Du evtl. Zeit ein Beispiel zu posten: Sagen wir, ich möchte eine 5 bit breite Maske bündig über ein, der Einfachheit halber, eindimensionales bit-Array der Größe, sagen wir mal 2^20 jagen. Ob Xor, Or oder And ist egal. Bin sehr gespannt! (mit bündig meine ich, dass jedes Bit des bit-Arrays bei einem Durchlauf genau 1x verarbeitet wird) > Timm R. schrieb: >> Die Pascal-Variante löst ein Problem, dass in der Version (Zugriff auf >> immer höchstens ein Bit pro Busbreite) nicht existiert... > > Bereitet es Dir persönlich Schmerzen, dass eine Hochsprache eine > elegante Lösung bietet, für die Du mit Deinem Makroassembler erst > irgendwelche Konstrukte erfinden musst? Nicht mein Makroassembler. Ich stehe nicht auf Formel 1. Ich benutze C++ oder Mathematica. Auch entstehen die Schmerzen nicht durch das Angebot, ich würde Pascal kein femto-bisschen schlechter finden, wenn es eingebaute String-Routinen für Blutegeltaxonomie gäbe. Tut ja nicht weh. Die Schmerzen entstehen, wenn Leute eine Sprache nicht etwa als "für mich ungeeignet" sondern als "Schei*" bezeichnen, nur weil sie nicht zärtlich genug auf ihre individuellen Wehwehchen eingeht. vlg Timm
Timm R. schrieb: > Karl schrieb: >> Du hast aber schon gesehen, dass es für TBits auch Xor, Or, And gibt, >> mit dem man einen Teil oder den kompletten Bitsatz bearbeiten kann? > > ok, das wäre natürlich dann schon sehr nice! Hättest Du evtl. Zeit ein > Beispiel zu posten: > > Sagen wir, ich möchte eine 5 bit breite Maske bündig über ein, der > Einfachheit halber, eindimensionales bit-Array der Größe, sagen wir mal > 2^20 jagen. Ob Xor, Or oder And ist egal. > > Bin sehr gespannt! hmmm, soll man das Schweigen im Walde jetzt so deuten, dass diese tollen bitweise adressierbaren Arrays in Pascal doch in der Anwendung auf die angesprochenen Megabyte großen Datenmengen (s.o. zB Bildverarbeitung) und praxisnahe Anwendungsszenarien ungeeignet sind? Much ado about nothing? gar-nicht-so-überraschte Grüße Timm
Ach vergiss den Karl... Der hat keine Ahnung von dem was er kritisiert. Hat er mehr als deutlich bewiesen. Macht hier den Pascal Priester, ohne zu merken, dass es für µC nahezu unbrauchbar ist. Begründungen werden ignoriert. Oder schlimmer, nicht nicht mal ignoriert, sondern offensichtlich gar nicht verstanden. Er hat es sich auf seinem Mount Stupid schön und bequem eingerichtet. Und kann davon nicht runter, weil er dann durch das Jammertal der Demut müsste. PS: Bitte, nicht falsch verstehen... Pascal gehört zu meinen Lieblingssprachen! C/C++ dagegen nicht wirklich. Aber dennoch ist es für meine AVR Arduino Zwerge das Mittel der Wahl. Brauchbare Alternativen sind weit und breit nicht in Sicht.
(Object)Pascal ist im Hinblick auf Booleans und Bits mit C(++) vollkommen identisch, sowohl die syntaktischen Möglichkeiten als auch die grundsätzlichen Einschränkungen derselben. Das ist auch kein Wunder denn die Einschränkungen kommen von der Hardware (Hardware deren kleinste adressierbare Einheit typischerweise mehr als ein Bit breit ist).
:
Bearbeitet durch User
c-hater schrieb: > Dass ich intellektuell mit diesem Schwachsinn nicht überfordert bin, > zeigen meine Kommentare. Dass hingegen du damit intellektuell > überfordert bist, zeigen wiederum deine Kommentare. Du willst halt > einfach nicht einsehen, dass deine bevorzugte Progammiersprache durchaus > massive systematische Schwächen hat. Jede Erwähnung dieser Schwächen > empfindest du als Blasphemie. Tatsache ist, daß C ein paar Schwächen hat, welche allerdings nicht halb so gravierend oder gar "massiv" sind, wie Du behauptest. Tatsache ist aber auch, daß Du Deinen Haß missionarisch in jedem Thread auswalzt, der nicht bei drei auf den Bäumen ist -- und Tatsache ist ebenso, daß diese gebetsmühlenartige und oft deplatzierte Missionierung manchmal ziemlich nervt.
Timm R. schrieb: > soll man das Schweigen im Walde jetzt so deuten, dass diese tollen > bitweise adressierbaren Arrays... ... oder so deuten, dass ich nicht Deine Nanny bin, und Besseres zu tun habe, als Beispielcode zu einem erfundenen Problem zu schreiben, der mir nichts nützt. Wenn es Dich interessiert, ich hab den Ansatz gegeben, Du kannst da gern ein Beispiel für schreiben und wenn Du damit Probleme hast, kannst Du wieder nachfragen. tl;dr: Ich muss nicht über jedes Stöckchen springen, das mir jemand hinhält. Arduino Fanboy D. schrieb: > Macht hier den Pascal Priester, ohne zu merken, dass es für µC nahezu > unbrauchbar ist. Dafür läuft meine von C auf Pascal portierte Heizungssteuerung und diverse andere Projekte auf µC aber erstaunlich gut. Ein Glück, dass meine µC hier nicht mitlesen können, dadurch wissen sie nicht, dass in Pascal geschriebener Code für sie unbrauchbar ist - und funktionieren trotzdem. Ist wie mit der Hummel... Arduino Fanboy D. schrieb: > Er hat es sich auf seinem Mount Stupid schön und bequem eingerichtet. Und das sagt ein "Arduino Fanboy". Gewagt, gewagt...
Karl K. schrieb: > Und das sagt ein "Arduino Fanboy". Gewagt, gewagt... Etwas Vorurteils behaftet... In aller Öffentlichkeit vom Namen auf ??? .. auf, was auch immer, zu schließen... Das wirft kein gutes Licht auf dich.
Karl K. schrieb: > Dafür läuft meine von C auf Pascal portierte Heizungssteuerung und > diverse andere Projekte auf µC aber erstaunlich gut. Die wäre mit C aber auch mit weniger Portierungsaufwand genausogut gelaufen. Insofern sagt das erstmal nix aus. Davon abgesehen ist es relativ egal, ob die Programmiersprache nun einen speziellen Bit-Datentypen anbietet oder nicht, denn die Hardware bietet es nicht (oder nur eingeschränkt) an. Sprachen, die fähig zu Metaprogrammierung sind - wie z.B. C++ - kann man ohnehin ohne zusätzliche Laufzeitkosten passend erweitern. Karl K. schrieb: > Ich muss nicht über jedes Stöckchen springen, das mir jemand hinhält. Musst du tatsächlich nicht. Ist aber auch eine Aussage.
Hallo, nein Karl, das ist so nicht in Ordnung. Du schriebst: Karl schrieb: > Timm R. schrieb: >> Der Fall, dass man in so einem bit-Array wirklich nur in jedem 32 oder >> 64 Bit Bereich genau ein Bit schreiben will, ist doch extrem exotisch. > > Du hast aber schon gesehen, dass es für TBits auch Xor, Or, And gibt, > mit dem man einen Teil oder den kompletten Bitsatz bearbeiten kann? auf meine Anmerkung, dass es ein extrem exotischer Fall ist, in einem großen Array ausschließlich auf einzelne Bits zuzugreifen. Der von mir angeführte Fall > Sagen wir, ich möchte eine 5 bit breite Maske bündig über ein, der > Einfachheit halber, eindimensionales bit-Array der Größe, sagen wir mal > 2^20 jagen. Ob Xor, Or oder And ist egal. ist ein typisches Beispiel. So oder vergleichbar werden 99% aller Fälle laufen, in denen man in großen Datensätzen Bits manipuliert. Hier wurde von jemandem Bildverarbeitung angeführt, den Algorithmus möchte ich gerne sehen, der nur alle 4 Byte ein Bit manipuliert, das ist doch total exotisch. Du behauptest: > Du hast aber schon gesehen, dass es für TBits auch Xor, Or, And gibt, > mit dem man einen Teil oder den kompletten Bitsatz bearbeiten kann? dass TBits solche Fälle lösen kann, das musst Du dann auch belegen, besonders, wenn die Dokumentation sagt, dass es das nicht kann und die von dir angeführten : > Du hast aber schon gesehen, dass es für TBits auch Xor, Or, And gibt, > mit dem man einen Teil oder den kompletten Bitsatz bearbeiten kann? für solche Fälle komplett nutzlos sind, zumindest laut Doku: https://www.freepascal.org/docs-html/rtl/classes/tbits.xorbits.html >XorBits performs a xor operation on the bits >in the array with the bits of array BitSet. >If BitSet contains less bits than the current array, >then all bits which have no counterpart in BitSet >are left untouched. >If the current array contains less bits >than BitSet then it is grown to the >size of BitSet before the xor operation is performed. Ich kann nicht erkennen, wie man damit effektive busbreite Bitmanipulationen gestalten will. vlg Timm
:
Bearbeitet durch User
Timm R. schrieb: > nein Karl, das ist so nicht in Ordnung. Das ahnt er sicherlich... Darum betreibt er auch gerade den "Aktiven Rückzug".
Timm R. schrieb: > dass TBits solche Fälle lösen kann, das musst Du dann auch belegen, Du musst jetzt sehr tapfer sein: Nein, muss ich nicht, und werde ich nicht. Ich habe TBits angeführt auf die Frage nach Bitmanipulation. Ob der Frager damit was anfangen kann, oder wie da die Performance ist... Karl schrieb: > Performance musst Du selbst testen. ... weiss ich nicht. Und es ist mir auch egal. Ich brauche es für meine aktuellen Projekte nicht, und habe es bisher nicht gebraucht. Wenn es Dich interessiert, probiere es selber aus. Wenn nicht, dann nicht.
Hi >In aller Öffentlichkeit vom Namen auf ??? .. auf, was auch immer, zu >schließen... Nö. Da gibt es ja noch die (mehrheitlichen) sinnfreien Beiträge die darunter stehen. Die bestimmen das Bild. MfG Spess
A. K. schrieb: > C wurde entwickelt, um auf kleinen Rechnern mit > wenig RAM verwendet werden zu können, ohne dafür > zig Durchläufe zu verwenden. Das prägte die > Sprache. Was in C selbst implementiert werden > kann, ohne dabei viel zu verlieren, blieb folglich > draussen. Das verstehe ich. Mein Punkt ist: Man kann sich des Eindrucks nicht erwehren, dass auch bei den Sachen, die in den Sprach- kern AUFGENOMMEN wurde, eine gewisse Willkür im Spiel war. Beispielsweise sehe ich nicht, was man mit Bitfeldern machen kann und was NICHT mit AND/OR/SHIFT auf Ganz- zahlen ausdrückbar wäre. Ich sehe den Zusatznutzen der Bitfelder nicht. Dabei geht es mir überhaupt nicht darum, aus sicherer zeitlicher Entfernung höhnisch über die Herrn K & R herzuziehen. Ganz im Gegenteil, meine Motivation ist viel egoistischer: Ich möchte verstehen, welche Konstrukte ich in C wirklich beherrschen muss -- und welche man ohne Schaden ignorieren kann. Bitfelder stehen bis jetzt auf meiner "Braucht man nicht wirklich"-Liste -- aber vielleicht ist das ja ein Fehler.
S. R. schrieb: > Davon abgesehen ist es relativ egal, ob die > Programmiersprache nun einen speziellen > Bit-Datentypen anbietet oder nicht, denn die > Hardware bietet es nicht (oder nur eingeschränkt) > an. Das ist kein sinnvolles Kriterium für eine höhere Programmiersprache. Strings, while-Schleifen, mehrdimensionale Arrays oder selbst Fließkommazahlen haben durchaus nicht immer eine 1:1-Entsprechung in der Hardware -- trotzdem will man das in der Hochsprache haben. Und umgekehrt genauso: Die Hardware kennt Register, aber ich bin ganz froh, wenn ich als Programmierer damit nix zu tun habe. Auf Pointer trifft im großen und ganzen dasselbe zu.
Egon D. schrieb: > Beispielsweise sehe ich nicht, was man mit Bitfeldern > machen kann und was NICHT mit AND/OR/SHIFT auf Ganz- > zahlen ausdrückbar wäre. Anfangs gab es auch keine. > Bitfelder stehen bis jetzt auf meiner "Braucht man > nicht wirklich"-Liste -- aber vielleicht ist das ja > ein Fehler. Lass sie drauf. Dennis Ritchie: `I added some things under some pressure from users that I don't think were done well. Enumeration types are a bit odd, bitfields are odder. The "static" keyword is very strange, expressing both a storage lifetime and what the standard calls "linkage" (external visibility). There are many odd bits here.´ (Im gleichen Interview offenbart Stroustrup, dass er kurz versuchte, die verkorkste Deklarationssyntax vom Kopf auf die Füsse zu stellen - vergeblich)
:
Bearbeitet durch User
Egon D. schrieb: > Dabei geht es mir überhaupt nicht darum, aus sicherer > zeitlicher Entfernung höhnisch über die Herrn K & R > herzuziehen. Ganz im Gegenteil, meine Motivation ist > viel egoistischer: Ich möchte verstehen, welche > Konstrukte ich in C wirklich beherrschen muss -- und > welche man ohne Schaden ignorieren kann. > > Bitfelder stehen bis jetzt auf meiner "Braucht man > nicht wirklich"-Liste -- aber vielleicht ist das ja > ein Fehler. Jain! Ich halte es für einen Fehler, solche Konstrukte nicht zu kennen! Das heißt nicht, dass man sie zum heiligen Gral erheben muss. Aber es ermöglicht einem auch fremde Programme zu lesen und zu verstehen, fast als wären es die eigenen. Willkürliche Einschränkungen beim lernen, verstopfen u.U. einfache Lösungswege. Beispiel: Goto Da scheiden sich auch die Geister... Es gibt eine große "Goto ist böse" Fraktion. Wo bei das doch ein erlaubtes Sprachmittel ist. Teil des Standards. Und für einige Anwendungsfälle sinnvoll einsetzbar. Es aus Dogmatismus abzulehnen ist schlicht dumm. Andererseits, im Übermaß eingesetzt, wirkt es wie ein Stock in den Speichen.
Egon D. schrieb: > Mein Punkt ist: Man kann sich des Eindrucks nicht > erwehren, dass auch bei den Sachen, die in den Sprach- > kern AUFGENOMMEN wurde, eine gewisse Willkür im Spiel > war. > Beispielsweise sehe ich nicht, was man mit Bitfeldern > machen kann und was NICHT mit AND/OR/SHIFT auf Ganz- > zahlen ausdrückbar wäre. Ich sehe den Zusatznutzen > der Bitfelder nicht. gerade im Embedded-Bereich sind Bitfelder doch eventuell ganz nett? Und bevor du hergehst und per AND/OR/SHIFT 2,3 oder 4 Bit Variablen manuell in ints zu verpacken, ist es doch 100x besser, einfach ein Bitfeld zu benutzen? Dann hast Du die "kleinen Variablen" aka Bitgruppen gleich sinnvoll benannt und durch den syntaktischen Zucker ist auch ohne Nachdenken klar, was du willst, während das aus den etwas unübersichtlicheren AND/OR/SHIFT Operationen nicht direkt folgt. vlg Timm
Egon D. schrieb: > Ich möchte verstehen, welche > Konstrukte ich in C wirklich beherrschen muss -- und > welche man ohne Schaden ignorieren kann. Das wirst du im Laufe der Zeit merken. Wenn du keine Ahnung hast, wie du eine Aufgabe lösen kannst, googelst du danach und findest z.B. bei StackOverflow mehrere Lösungsansätze. Manche davon verstehst du vielleicht nicht, weil du die Sprache nicht vollständig kennst. Das ist aber egal, solange du deine Aufgabe lösen kannst. Das gilt für alle Programmiersprachen. Das Lesen fremder Quelltexte erfordert sehr viel mehr Kenntnisse, denn man mus alle Sprachelemente und Patterns kennen, die die anderen verwendet haben. Deswegen ist die Aufbereitung alter Programme eine Aufgabe für die fortgeschrittenen Entwickler. > Bitfelder stehen bis jetzt auf meiner "Braucht man > nicht wirklich"-Liste Glaube mir, du wirst es nicht bereuen. Wenn du mal zu C++ kommst, dann schiebe Operator-Überladung, Exceptions und Templates erstmal weit nach hinten. Auch darauf kann man lange weitgehend verzichten und dennoch großartige Programme schreiben Dafür werte ich jetzt wahrscheinlich verhöhnt. Macht ruhig, ist mir egal.
Stefanus F. schrieb: > Dafür werte ich jetzt wahrscheinlich verhöhnt. Habe kein Interesse daran, dich zu verhöhnen! Bin sogar in Grenzen bereit dir zuzustimmen. Denn irgendwo muss man ja anfangen zu lernen Auch von einem Kleinkind darf man nicht erwarten, dass es sofort perfekte Romane raus haut. > Lernen ist ein Prozess! > Wir lernen, in dem wir es tun. Die Gefahr des Ausblendens besteht darin dass man freiwillig auf dem Niveau einer "Kleinkind Brabbelsprache" stehen bleibt. Man wird dadurch zum einsamen König, auf der Insel der Dummheit. Es macht wenig Sinn, die mächtigen Instrumente (Operatorenüberladung/Templates), der Sprache C++, auszublenden. -- Jahre ziehen ins Land, bis man vieles begriffen hat. Umsteiger, z.B. von Java oder Pascal, tun sich oft sehr schwer mit diesen C++ Konzepten. Bilden innere Widerstände aus. Anfänger haben es da eher einfacher.
Egon D. schrieb: > Beispielsweise sehe ich nicht, was man mit Bitfeldern > machen kann und was NICHT mit AND/OR/SHIFT auf Ganz- > zahlen ausdrückbar wäre. Das trifft auf viele Befehle zu, die man sicher auch nicht braucht, die aber ganz nett sein können.
1 | var |
2 | LEDPort: bitpacked record |
3 | red, green, yellow, blue: boolean; |
4 | end absolute PORTD; |
5 | |
6 | begin |
7 | LEDPort.red := true; |
8 | LEDPort.green := true; |
9 | LEDPort.yellow := false; |
10 | LEDPort.blue := false; |
ist doch mal schöner anzusehen als
1 | #define LEDPort PORTD |
2 | #define red PD0 |
3 | #define green PD1 |
4 | #define yellow PD2 |
5 | #define blue PD3 |
6 | |
7 | LEDPort |= (1 << red); |
8 | LEDPort |= (1 << green); |
9 | LEDPort &= ~(1 << yellow); |
10 | LEDPort &= ~(1 << blue); |
Ups, man kann bitpacked records auf Portpins anwenden? Wie kann das sein, wenn doch Pascal auf dem µC nahezu unbrauchbar ist?
Arduino Fanboy D. schrieb: > Es macht wenig Sinn, die mächtigen Instrumente > (Operatorenüberladung/Templates), der Sprache C++, auszublenden. > > -- > Jahre ziehen ins Land, bis man vieles begriffen hat. > > Umsteiger, z.B. von Java oder Pascal, Pascal hat (heutzutage) ebenfalls Operatorüberladung und Generics.
A. K. schrieb: >> Bitfelder stehen bis jetzt auf meiner "Braucht man >> nicht wirklich"-Liste -- aber vielleicht ist das ja >> ein Fehler. > > Lass sie drauf. Danke! > Dennis Ritchie: `I added some things under some pressure > from users that I don't think were done well. Enumeration > types are a bit odd, bitfields are odder. Sehr interessant :)
Arduino Fanboy D. schrieb: >> Bitfelder stehen bis jetzt auf meiner "Braucht man >> nicht wirklich"-Liste -- aber vielleicht ist das ja >> ein Fehler. > > Jain! > Ich halte es für einen Fehler, solche Konstrukte nicht > zu kennen! Klar -- das ging zwar aus meinem Text nicht direkt hervor, aber ich mache einen Unterschied zwischen "kennen" und "beherrschen". "Kennen", d.h. lesen und ungefähr verstehen können muss man alle Konstrukte der Sprache. "Beherrschen" muss man dagegen nur einen Teil -- nämlich den Teil, den man benötigt, um seine Probleme zu lösen.
Als Beispiel wird ein Byte für 8 Bool Variablen genutzt. Ich verwende diese Quellen:
1 | #include <BitBool.h> |
2 | // https://github.com/Chris--A/BitBool
|
3 | uint8_t Display_Status_new = 0; // Switch up / down |
4 | // https://github.com/Chris--A/BitBool#reference-a-single-bit-of-another-object-or-bitbool---
|
5 | auto bit_0 = toBitRef( Display_Status_new, 0 ); // ( "0" ) Create a bit reference to first bit. |
6 | auto bit_1 = toBitRef( Display_Status_new, 1 ); // ( "." ) |
7 | auto bit_2 = toBitRef( Display_Status_new, 2 ); // ( "+/-" ) |
8 | auto bit_3 = toBitRef( Display_Status_new, 3 ); // ( "EE" ) |
9 | auto bit_4 = toBitRef( Display_Status_new, 4 ); // ( "FN" ) |
10 | auto bit_5 = toBitRef( Display_Status_new, 5 ); // ( "=" ) |
11 | auto bit_6 = toBitRef( Display_Status_new, 6 ); // ( "M+" ) |
Dies funktioniert bei mir.
:
Bearbeitet durch User
c-hater schrieb: > S. R. schrieb: > >> Im Übrigen hat zumindest der SDCC für manche Architekturen eine >> spezifische Optimierung von "bool", um hardwareseitig vorhandene >> Einzelbitregister sinnvoll nutzen zu können. Solch ein bool belegt real >> dann tatsächlich nur ein Bit. > > Ja, klar, und dieser Kram ist dann genauso portabel wie Assemblercode. > Damit ist jegliches Argument für die Verwendung von C ganz unmittelbar > vom Tisch... Ich sehe da kein Portabilitätsproblem. Man verwendet z.B. eine lokale bool-Variable. Die funktioniert so, wie der C-Standard es vorschreibt. Ob der Compiler diese im Speicher, in einem 8-bit-Register, im carry-Flag ablegt, oder ganz wegoptimiert ist kein Problem für die Portabilität. Und das mcs51-Backend von SDCC legt halt bis zu 8 bool gleichzeitig in Einzelbitregistern ab, um Speicherplatz / Register zu sparen. Philipp
foobar schrieb: >> Nennt sich bitfield und wird je nach Arduino (AVR oder ARM, opcodes >> anderer kenne ich nicht gut genug) zumindest im Falle von einzelnen >> Bits recht kompakten Code erzeugen. > > Dummerweise sind Bitfields so schwach definiert, dass man sie kaum > sinnvoll nutzen kann. Weder ist die Reihenfolge noch das Packing > definiert. So könnte in deinem Beispiel das Feld f1 das höchst- oder das > niederwertigste Bit sein, oder gar jedes Feld ein einzelnes Byte/Word > belegen. Da sie außerdem nicht adressierbar sind (&-Operator), sind sie > irgendwie eine Fremdkörper im System - ein schwarzes Schaf ;-) Bit-fields sind sehr nützlich, um Speicherplatz zu sparen. Zwar wird für den Zugriff vom Compiler oft mehr Code generiert, aber für ein bit-field im RAM eines µC, der deutlich mehr ROM (Flash, etc) als RAM hat ist es oft trotzdem sinnvoll. bit-fields zu verwenden. Philipp
Philipp Klaus K. schrieb: > c-hater schrieb: >> S. R. schrieb: >> >>> Im Übrigen hat zumindest der SDCC für manche Architekturen eine >>> spezifische Optimierung von "bool", um hardwareseitig vorhandene >>> Einzelbitregister sinnvoll nutzen zu können. Solch ein bool belegt real >>> dann tatsächlich nur ein Bit. >> >> Ja, klar, und dieser Kram ist dann genauso portabel wie Assemblercode. >> Damit ist jegliches Argument für die Verwendung von C ganz unmittelbar >> vom Tisch... > > Ich sehe da kein Portabilitätsproblem. Man verwendet z.B. eine lokale > bool-Variable. Die funktioniert so, wie der C-Standard es vorschreibt. > Ob der Compiler diese im Speicher, in einem 8-bit-Register, im > carry-Flag ablegt, oder ganz wegoptimiert ist kein Problem für die > Portabilität. OK, dann nehmen wir halt mal den Keil C51 Compiler der mit den kleinen ultrabilligen Silabs BusyBee EFM8BBxxxx 8051 basierenden Controllern ausgeliefert wird und dem zugehörigen SDK und dessen kaputten stdbool.h was Silabs verbockt hat. Das speichert bool tatsächlich als 1 Bit irgendwo in einer Keil-spezifischen "bit"-Variable. bool foo[24]; *** ERROR C168 IN LINE 35 OF /what/ever/test.c: 'foo': array of bit Das ist ein großer halbgarer Krampf hoch 3 und es ist vollkommen unportabel! Jetzt muss ich überall char hinschreiben wo ich der Lesbarkeit zuliebe eigentlich lieber bool hätte sagen wollen. Da hätten die lieber diesen halbgaren Datentyp "bit" links liegen lassen sollen und das gute alte bool genau so definieren sollen wie es sonst auch überall ist (einzeln adressierbar, also mindestens 1 char breit).
:
Bearbeitet durch User
Bernd K. schrieb: > Das speichert bool tatsächlich als 1 Bit > irgendwo in einer Keil-spezifischen "bit"-Variable. Der 8051 kann einige Bits im RAM direkt ansprechen... > *** ERROR C168 IN LINE 35 OF /what/ever/test.c: 'foo': array of bit ...aber eben nur direkt, nicht berechnet.
Bernd K. schrieb: > dann nehmen wir halt mal den Keil C51 Compiler Dann gratuliere ich dir, erfolgreich einen kaputten Compiler als Maßstab für eine Programmiersprache zu nehmen.
S. R. schrieb: > Dann gratuliere ich dir, erfolgreich einen kaputten Compiler als Maßstab > für eine Programmiersprache zu nehmen. Ich nehme ihn nicht als Maßstab für irgendwas, ich führe ihn als warnendes Beispiel an! Außerdem hat Silabs hier erhebliche Mitschuld, deren stdbool.h definiert bool auf diese falsche und inkompatible Weise, ansonsten hätte dieser eingebaute Spezialtyp "bit" des Compilers überhaupt keinen unbeabsichtigten Schaden angerichtet.
:
Bearbeitet durch User
Bernd K. schrieb: >> Dann gratuliere ich dir, erfolgreich einen kaputten Compiler >> als Maßstab für eine Programmiersprache zu nehmen. > Ich nehme ihn nicht als Maßstab für irgendwas, ich führe ihn als > warnendes Beispiel an! Wer eine fehlerhafte Implementation zur Grundlage macht, um vor Sprachfeatures zu warnen, der nimmt diese fehlerhafte Implementation als Maßstab (nach unten) für andere Implementationen. Tschuldigung, aber die Aussage "der Keil C51 kann das aber nicht" hat so nahezu keine praktische Relevanz für nahezu alle C-Programmierer. Ausgenommen sind diejenigen, die den Keil C51 benutzen müssen oder wollen - und die sollten sich mit ihrem Compiler auskennen. AVR-GCC und SDCC können auch kein richtiges "double", obwohl es im Standard steht. Darf ich das jetzt auch nicht mehr benutzen?
Hat es schon jemand probiert? Diese Implementation sollte Prozessorunabhängig sein. https://github.com/Chris--A/BitBool
S. R. schrieb: > Wer eine fehlerhafte Implementation zur Grundlage macht, um vor > Sprachfeatures zu warnen, der nimmt diese fehlerhafte Implementation als > Maßstab (nach unten) für andere Implementationen. Es kann keine "nicht fehlerhafte" Implementation dieses "Features" geben weil ein einzelnes Bit auf so gut wie keiner einzigen gebräuchlichen Plattform einzeln adressierbar ist. Man kann keine Arrays damit bauen, man kann keinen Zeiger darauf bekommen, keinen Offset in einem Struct, etc. Das hat überhaupt nichts mit dem Keil-Compiler zu tun, das hätte auch kein anderer Compiler geschafft weil es schlichtweg unmöglich ist! Der Keil in Zusammenarbeit mit dem Silabs SDK diente hier nur als Beispiel um zu zeigen was passiert wenn man es dennoch versucht und dann auch noch in den mitgelieferten Headern den Datentyp "bool" so umdefiniert daß er auf diesem verkrampften Halbdatentyp basiert. Ich weiß nicht warum Du dauernd auf "kaputter Compiler" herumreitest, der Keil ist vielleicht aus anderen Gründen kaputt, das hier gehört aber nicht dazu, das hat Silabs mit seinem SDK verbockt weil sie ein Keil-"Feature" verwendet haben für etwas wofür es niemals vorgesehen war.
Bernd K. schrieb: > Es kann keine "nicht fehlerhafte" Implementation dieses "Features" geben > weil ein einzelnes Bit auf so gut wie keiner einzigen gebräuchlichen > Plattform einzeln adressierbar ist. Ja. Das hindert einen Compiler aber nicht daran, einzelne Bits zu benutzen, wenn die Adressierbarkeit nicht benötigt wird. Stichwort as-if-rule. Wenn ich Adressierbarkeit verlange, dann muss ich nunmal ein Dingens haben, was ich auch adressieren kann, und das ist in C mindestens ein "char". Daran ist aber nicht C schuld, sondern die zugrundeliegende Hardware. Bernd K. schrieb: > Das hat überhaupt nichts mit dem Keil-Compiler zu tun, das hätte auch > kein anderer Compiler geschafft weil es schlichtweg unmöglich ist! Nö. Ein korrekter Compiler - beziehungsweise korrekter: eine korrekte Implementation - hätte deinen "bool" als die kleinste hardwareseitig adressierbare Einheit (char oder größer) implementiert. Als lokale Variable ist ein Einzelbit vollkommen möglich und legal - siehe SDCC. Bernd K. schrieb: > Ich weiß nicht warum Du dauernd auf "kaputter Compiler" > herumreitest, [...] das hat Silabs mit seinem SDK verbockt Okay, dann nehme ich das mit dem Keil zurück und zeige auf Silabs. An meiner Kritik ändert es trotzdem nichts.
Bernd K. schrieb: > weil ein einzelnes Bit auf so gut wie keiner einzigen gebräuchlichen > Plattform einzeln adressierbar ist. Naja, das ist Auslegungssache. Auf dem AVR kann man einzelne Portpins addressieren, einzelne Bits in den höheren Registern und einzelne Bits im Statusregister. Und auf den meisten Archtekturen dürfte man einzelne Bits zumindest im Statusregister ansprechen.
Karl K. schrieb: > Bernd K. schrieb: >> weil ein einzelnes Bit auf so gut wie keiner einzigen gebräuchlichen >> Plattform einzeln adressierbar ist. > > Naja, das ist Auslegungssache. Auf dem AVR kann man einzelne Portpins > addressieren, einzelne Bits in den höheren Registern und einzelne Bits > im Statusregister. Mit Verlaub, im Kontext von C ist das schlicht falsch. Im Kontext von C bedeutet "adressierbar", daß der & (vulgo: "address-of") Operator einen Zeiger auf das derart referenzierte Datenobjekt liefert. Und das funktioniert nun mal nicht für einzelne Bits. Die kleinste Dateneinheit, für die das in C funktioniert, heißt Byte. > Und auf den meisten Archtekturen dürfte man einzelne Bits zumindest im > Statusregister ansprechen. "ansprechbar" und "addressierbar" sind verschiedene Konzepte. Natürlich kann man auch in C einzelne Bits ansprechen. Entweder per Bitoperation oder - innerhalb eines bit fields - auch per Namen.
Axel S. schrieb: > Karl K. schrieb: >> Bernd K. schrieb: >>> weil ein einzelnes Bit auf so gut wie keiner einzigen gebräuchlichen >>> Plattform einzeln adressierbar ist. >> >> Naja, das ist Auslegungssache. Auf dem AVR kann man einzelne Portpins >> addressieren, einzelne Bits in den höheren Registern und einzelne Bits >> im Statusregister. > > Mit Verlaub, im Kontext von C ist das schlicht falsch. Im Kontext von C > bedeutet "adressierbar", daß der & (vulgo: "address-of") Operator einen > Zeiger auf das derart referenzierte Datenobjekt liefert. Und das > funktioniert nun mal nicht für einzelne Bits. Die kleinste > Dateneinheit, für die das in C funktioniert, heißt Byte. Das muß man nicht mal C anlasten. Auch die Hardware kennt keine Pointer-Zugriffe auf Bits. Nur hart im Maschinenbefehl hinterlegt geht ein solcher Zugriff. Gut, man kann über den Umweg "Flash patchen" Bit-Pointer realisieren, aber das dauert und nach 10k Zugriffen könnte der Flash kaput sein. Man sollte sich drauf einigen: es gibt keine Bit-Pointer bei AVR.
Axel S. schrieb: > Im Kontext von C > bedeutet "adressierbar", daß der & (vulgo: "address-of") Operator einen > Zeiger auf das derart referenzierte Datenobjekt liefert. So what. Ich wüßte nicht, dass mir das jemals gefehlt hätte. Vielleicht fehlt mir dazu auch das C-Gen, auf alles pointern zu müssen. Ich weiss, wie ich an einzelne Bits und Portpins auf dem AVR rankommen, und das ausreichend komfortabel. Mit welcher Adresse das passiert, darum darf sich der Compiler kümmern, und da ich immer mal in den erzeugten Maschinencode schaue, weiss ich auch, dass der FPC seine Sache in dieser Beziehung gut macht.
Axel S. schrieb: > Im Kontext von C bedeutet "adressierbar", daß der & (vulgo: > "address-of") Operator einen Zeiger auf das derart > referenzierte Datenobjekt liefert. Korrekt. Das impliziert aber gerade nicht, dass jedes Objekt auch adressierbar sein muss. Und damit drehen wir noch eine Runde im Kreis. :-)
S. R. schrieb: > Axel S. schrieb: >> Im Kontext von C bedeutet "adressierbar", daß der & (vulgo: >> "address-of") Operator einen Zeiger auf das derart >> referenzierte Datenobjekt liefert. > > Korrekt. Das impliziert aber gerade nicht, dass jedes Objekt auch > adressierbar sein muss. Aber dass es für jeden Datentyp möglich sein muss, ein adressierbares Objekt (und auch ein Array) dieses Typs zu erstellen.
Rolf M. schrieb: > Aber dass es für jeden Datentyp möglich sein muss, ein adressierbares > Objekt (und auch ein Array) dieses Typs zu erstellen. Ist es doch, die Adresse ist die Adresse des Bytes, Words oder Longwords, in dem die Boolean Variable gespeichert ist. Und wenn die Boolean Variable gepackt ist, dann eben die Adresse des Bytes, Words oder Longwords, welches das gepackte Bit enthält. Oder heulst Du auch rum, weil Dir ein Pointer auf ein Char die Adresse eines Longwords zurückgibt, da es für ein 64-bit System effizienter zu verwalten ist?
Karl K. schrieb: > Rolf M. schrieb: >> Aber dass es für jeden Datentyp möglich sein muss, ein adressierbares >> Objekt (und auch ein Array) dieses Typs zu erstellen. > > Ist es doch, die Adresse ist die Adresse des Bytes, Words oder > Longwords, in dem die Boolean Variable gespeichert ist. Du verstehst nicht. C hat eigentlich keine Arrays, sondern verwendet einen Pointer (auf das erste Element) und Pointer-Arithmetik. Die Notation mit eckigen Klammern und einem Index ist nur syntaktischer Zuckerguß. Wenn es für einen Datentyp keine Pointer *auf ein einzelnes Element* gibt, dann kann C kein Array daraus bauen. Ein Pointer auf ganze Bytes reicht nicht. Was gepackte Bits ganz besonders nutzlos macht, denn Platz spart man mit denen ja erst dann, wenn man mehrere davon in ein Array packt. C++ umschifft diese Klippe, weil es kundenspezifische Iteratoren (ein generalisiertes Konzept für Zeiger in einem Container) erlaubt.
:
Bearbeitet durch User
Karl K. schrieb: > Ist es doch, die Adresse ist die Adresse des Bytes, Words oder > Longwords, in dem die Boolean Variable gespeichert ist. Die Adresse zweier benachbarter Bits im Container wäre dann gleich. Wären solche Bits als normale Objekte zulässig, würde das aufgrund logischer Analogie auch C Implementierungen zulassen, in denen benachbarte chars im String die gleiche Adresse haben.
Karl K. schrieb: > Oder heulst Du auch rum, weil Dir ein Pointer auf ein Char die Adresse > eines Longwords zurückgibt, Was nur dann der Fall sein könnte, wenn die Darstellung eines Chars ein ganzes Longword frisst. Und folgerichtig ein String einem Array of Longword entspricht. Mindestens 99% aller Programmierer würden sich allerdings fragen, welches schlechte Kraut der Compilerbauer dabei geraucht hat. Auch Maschinen ohne Byteadressierung haben mehrere Chars in ein Wort gepackt, beispielsweise 10 Chars in ein 60-Bit Wort. Stringverarbeitung wie in C ist dann auf Maschinenebene recht spassbefreit und benötigt Pointer, die eine Adresse des Wortes und eine Position darin codieren.
:
Bearbeitet durch User
Karl K. schrieb: > Rolf M. schrieb: >> Aber dass es für jeden Datentyp möglich sein muss, ein adressierbares >> Objekt (und auch ein Array) dieses Typs zu erstellen. > > Ist es doch, die Adresse ist die Adresse des Bytes, Words oder > Longwords, in dem die Boolean Variable gespeichert ist. Dann kann ich aber eben nur eine davon pro Byte abspeichern, denn sonst würden mehrere separate Variablen die gleiche Adresse haben, was aus offensichtlichen Gründen nicht zulässig ist. > Und wenn die Boolean Variable gepackt ist, dann eben die Adresse des > Bytes, Words oder Longwords, welches das gepackte Bit enthält. Und welche Magie benutzt der Compiler dann, um auf das richtige Bit zuzugreifen, wenn der Zeiger keine Information darüber enthält, um welches Bit innerhalb des Bytes es überhaupt geht? > Oder heulst Du auch rum, weil Dir ein Pointer auf ein Char die Adresse > eines Longwords zurückgibt, da es für ein 64-bit System effizienter zu > verwalten ist? Ein Pointer auf ein char enthält per Definition die Adresse eines char. Welche Adresse das ist, spielt dabei für den Anwender keine Rolle, solange jeder char eine eigene Adresse hat.
Rolf M. schrieb: > Und welche Magie benutzt der Compiler dann, um auf das richtige Bit > zuzugreifen, wenn der Zeiger keine Information darüber enthält, um > welches Bit innerhalb des Bytes es überhaupt geht? Schwarze Magie, denn sonst würde es nicht funktionieren, und bekanntlich funktioniert es. Ist diese zwanghafte Fixierung auf Pointer eigentlich behandelbar?
Karl K. schrieb: > Ist diese zwanghafte Fixierung auf Pointer eigentlich behandelbar? Nein! C geht nicht ohne Pointer! Ein Kernelement der Sprache. Es gibt keine Referenzen in C. Ist dein Pascal Priestertum eigentlich behandelbar?
Karl K. schrieb: > Rolf M. schrieb: >> Und welche Magie benutzt der Compiler dann, um auf das richtige Bit >> zuzugreifen, wenn der Zeiger keine Information darüber enthält, um >> welches Bit innerhalb des Bytes es überhaupt geht? > > Schwarze Magie, denn sonst würde es nicht funktionieren, und bekanntlich > funktioniert es. > > Ist diese zwanghafte Fixierung auf Pointer eigentlich behandelbar? Als ich vor Jahrzehnten, nach einem Semester FOTRAN-Folter in einem Semesterferienkurs den ersten Kontakt zu Pascal hatte, hatte es mir ein Detail ganz besonders angetan: POINTER Das hielt solange an, bis es bezahlbare (ok, hat man damals auch nicht lieber als heute gemacht, sozusagen GPL vorgegriffen) C-Compiler gab. Die hatten so eingebaute Code-Comprimierung: begin -> { (5:1) und end -> } immer noch 3:1. Das war cool.
:
Bearbeitet durch User
Carl D. schrieb: > Das war cool. Jaja, damals, als es noch kein Autocomplete gab... da war das bestimmt cool.
Karl K. schrieb: > Ist diese zwanghafte Fixierung auf Pointer eigentlich behandelbar? Nur durch deine unbedingte und totale Abstinenz von C,C++,D,... Jeglicher Anblick solchen Quellcodes riskiert sofortigen Rückfall, mit Ausfluss ins Forum.
:
Bearbeitet durch User
Karl K. schrieb: > Carl D. schrieb: >> Das war cool. > > Jaja, damals, als es noch kein Autocomplete gab... da war das bestimmt > cool. Es ging um Pointer und die hatte 1970 schon wer? Bestimmt nicht der, der erst 1972 entworfen wurde. Die "zwanghafte Fixierung auf Pointer" wurde von einem Herrn Wirth schon vor dem Herrn Ritchie in eine Sprachdefinition gegossen. Aber einmal ist sie gut und einmal böse.
Carl D. schrieb: > Es ging um Pointer und die hatte 1970 schon wer? Beispielsweise die zweitälteste noch genutzte Hochsprache: Lisp, 1958. Wer schon bei Pointern in C einen Anfall kriegt, der verdampft bei Lisp sofort und rückstandsfrei.
:
Bearbeitet durch User
A. K. schrieb: > Wer schon bei Pointern in C einen Anfall kriegt, der verdampft bei Lisp > sofort und rückstandsfrei. Oh ja. Bitte, bitte!
Axel S. schrieb: > Oh ja. Bitte, bitte! Ich auch! Lisp? Mindestens 1,2m Abstand. Mindestens! Forth, ok. Aber Lisp? Neee---
A. K. schrieb: > Carl D. schrieb: >> Es ging um Pointer und die hatte 1970 schon wer? > > Beispielsweise die zweitälteste noch genutzte Hochsprache: Lisp, 1958. > Wer schon bei Pointern in C einen Anfall kriegt, der verdampft bei Lisp > sofort und rückstandsfrei. Bitte beachten: der Karl mit der Pointerallergie schreibt sich nicht mit "C". Ich schon, denn ich bekomme keine Pusteln, wenn ich "&", "*" oder "->" sehe. Ob die Namenschreibweise mit Programmiersprachenaffinität zu tun hat? Who knows? ;-)
Carl D. schrieb: > Bitte beachten: Sorry - du warst damit allerdings auch nicht gemeint. Hattest bloss die richtige Frage gestellt. ;-)
Carl D. schrieb: > Es ging um Pointer und die hatte 1970 schon wer? > Bestimmt nicht der, der erst 1972 entworfen wurde. > > Die "zwanghafte Fixierung auf Pointer" wurde von > einem Herrn Wirth schon vor dem Herrn Ritchie in > eine Sprachdefinition gegossen. Das ist deshalb Unsinn, weil "hat auch" nicht dasselbe bedeutet wie "ist zwanghaft fixiert auf". Da Du Wirth erwähnst, wirst Du wohl auf Pascal anspielen. In Pascal kann man problemlos mit Array arbeiten, ohne sich um Pointer irgendwie zu kümmern; für Strings gilt im Prinzip dasselbe. Pointer kommen erzwungendermaßen erst bei "dynamischen Variablen" ins Spiel; hier beschränkt sich das Herum- gepointere auf Speicher reservieren, Speicher freigeben und Pointer zuweisen.
Carl D. schrieb: > Es ging um Pointer und die hatte 1970 schon wer? > Bestimmt nicht der, der erst 1972 entworfen wurde. Die späteren Versionen aus der Algol-Sprachfamilie?
Egon D. schrieb: > In Pascal kann man problemlos mit Array arbeiten, ohne > sich um Pointer irgendwie zu kümmern; für Strings gilt > im Prinzip dasselbe. Kann man in C auch. Allerdings dürfen in C Strings auch nahezu beliebig lang sein. Egon D. schrieb: > Pointer kommen erzwungendermaßen erst bei "dynamischen > Variablen" ins Spiel; hier beschränkt sich das Herum- > gepointere auf Speicher reservieren, Speicher freigeben > und Pointer zuweisen. Also wie in C auch:
1 | int *array = malloc(128*sizeof(int)); |
2 | array[0] = 1; |
3 | array[1] = 4; |
4 | array[2] = 7; |
5 | printf("%d\n", array[0]); |
6 | free(array); |
Pointer werden erst dann spannend, wenn man damit komplexere Dinge machen will.
Carl D. schrieb: > Es ging um Pointer und die hatte 1970 schon wer? Nein, es geht in Deinem Beitrag um Codekomprimierung durch Klammerung. Kannst Du jetzt schon Deine eigenen Beiträge nicht mehr inhaltlich erfassen? Zur Erinnerung: Carl D. schrieb: > Die hatten so eingebaute Code-Comprimierung: begin -> { (5:1) und end -> > } immer noch 3:1. Das war cool.
S. R. schrieb: > Kann man in C auch. Allerdings dürfen in C Strings auch nahezu beliebig > lang sein. Die Viren wissen es zu schätzen, sind diese nullterminierten Strings doch immer wieder für Bufferüberläufe gut. Falls Du auf die 255 Zeichen Begrenzung bei Pascal-Strings anspielt: Schon lange nicht mehr.
Carl D. schrieb: > Ob die Namenschreibweise mit Programmiersprachenaffinität zu tun hat? Hieße die Sprache Paskal, wäre es eindeutiger.
Liebster Karl... In diesem Thread dreht es sich nicht darum, was die geilste Programmiersprache ist, C, C++ oder Pascal. Sondern um Boolean Variablen/Daten auf und mit Arduino. Und dabei ist es doch völlig egal, ob dir das Pointer Konzept von C und C++ schmeckt, oder auch nicht. Deine gesammelten Pascal Werbemaßnahmen sind für dieses Thema absolut irrelevant. Klartext: Dein verbohrtes Priestertum widert mich an!
Beitrag #5608330 wurde vom Autor gelöscht.
S. R. schrieb: > Egon D. schrieb: >> In Pascal kann man problemlos mit Array arbeiten, ohne >> sich um Pointer irgendwie zu kümmern; für Strings gilt >> im Prinzip dasselbe. > > Kann man in C auch. Dein sinnentstellendes Zitieren macht keinen Spaß. Es ging nicht darum, was man in Pascal oder C könnte oder nicht könnte -- es ging darum, dass Pointer ein integraler Bestandteil von C sind, nicht aber von Pascal. > Pointer werden erst dann spannend, wenn man damit > komplexere Dinge machen will. Da unterscheiden wir uns eben grundlegend. Ich finde Pointer generell nicht spannend, sondern ein Furunkel am Arsch. Ich meine, eine Darmspiegelung oder das Auspumpen meines Magens finde ich auch nicht spannend -- auch wenn ich zugebe, dass es mir das Leben retten kann. Es ist mir deutlich lieber, wenn ich ohne auskomme.
Rufus Τ. F. schrieb: > Carl D. schrieb: >> Ob die Namenschreibweise mit Programmiersprachenaffinität zu tun hat? > > Hieße die Sprache Paskal, wäre es eindeutiger. Wenigstens einer der sich nicht in der Kunst des Mißverstehens suhlt.
:
Bearbeitet durch User
Arduino Fanboy D. schrieb: > Sondern um Boolean Variablen/Daten auf und mit Arduino. > Und dabei ist es doch völlig egal, ob dir das Pointer Konzept von C und > C++ schmeckt, oder auch nicht. Nur braucht man für Booleans und bitpacked Booleans weder unter Pascal noch unter C(++) jemals irgendeinen Pointer anzufassen, um sie zu verwenden. Daher ist dieses ständige Rumgereite auf den Pointern "aber ich kann darauf nicht rumpointern, also akzeptiere ich das nicht" einfach nur eine Zwangsvorstellung. Und Du musst jetzt sehr tapfer sein: Pascal läuft auch auf Arduinos.
Karl K. schrieb: > Daher ist dieses ständige Rumgereite auf den Pointern "aber ich kann > darauf nicht rumpointern, also akzeptiere ich das nicht" einfach nur > eine Zwangsvorstellung. Man kann Programmiersprachen definieren, ohne darin auf Pointer zurückzugreifen. Aber man kann aus C/C++ keine solche Sprache mehr machen, ohne daraus eine signifikant andere Sprache zu machen. Wer also dauernd auf den Pointern in C/C++ herumreitet, der sitzt schlicht im falschen Zug.
Karl K. schrieb: > Ist diese zwanghafte Fixierung auf Pointer eigentlich behandelbar? In Pascal funktionieren die Pointer, die Arrays und die eckigen Klammern übrigens exakt genauso wie in C, der selbe syntaktische Zucker zum Dereferenzieren eines Pointers mit Offset in Eckiger-Klammer-Arrayschreibweise:
1 | program project1; |
2 | |
3 | {$mode objfpc}{$H+} |
4 | |
5 | var |
6 | foo: array[0..15] of Byte; |
7 | bar: PByte; |
8 | |
9 | begin |
10 | foo[3] := 42; |
11 | bar := foo; // array liefert einen Pointer, wie in C |
12 | writeln(bar[3]); // pointer wie array dereferenziert |
13 | writeln((bar + 3)^); // das selbe ohne Syntaxzucker |
14 | end. |
$ ./project1 42 42 Die Sprachen sind sich unter der Haube sehr ähnlich, man macht die selben Sachen (nur schöner) und der Compiler wird ähnlichen Code erzeugen. Es ist nur ne intuitivere Syntax, mehr Typsicherheit und ein gescheites Modulsystem, alles andere ist exakt wie C.
:
Bearbeitet durch User
Bernd K. schrieb: > Es ist nur ne intuitivere Syntax, mehr Typsicherheit und ein > gescheites Modulsystem, alles andere ist exakt wie C. In Pascal steht ein Array für das Array, in C/C++ meist für einen Pointer auf das erste Element. Das ist ein recht bedeutender Unterschied, beispielsweise bei der Übergabe von Parametern.
A. K. schrieb: > Bernd K. schrieb: >> Es ist nur ne intuitivere Syntax, mehr Typsicherheit und ein >> gescheites Modulsystem, alles andere ist exakt wie C. > > In Pascal steht ein Array für das Array, in C/C++ meist für einen > Pointer auf das erste Element. Das ist ein recht bedeutender > Unterschied, beispielsweise bei der Übergabe von Parametern. Bitteschön:
1 | program project1; |
2 | |
3 | {$mode objfpc}{$H+} |
4 | |
5 | var |
6 | foo: array[0..15] of Byte; |
7 | bar: PByte; |
8 | |
9 | function baz(P: PByte; I: Byte):Byte; |
10 | begin |
11 | Result := P[I]; // Pointer wie "Array" behandelt |
12 | end; |
13 | |
14 | begin |
15 | foo[3] := 42; |
16 | bar := foo; |
17 | writeln(bar[3]); |
18 | writeln((bar + 3)^); |
19 | |
20 | writeln(baz(foo, 3)); // array an Funktion übergeben die gleichtypigen Pointer erwartet |
21 | end. |
$ ./project1 42 42 42 Im Speicher ist ein Array ein Array, alles andere ist Syntaxzucker. Der Umgang damit (und der Zucker) ist in Pascal wie in C vollkommen identisch.
Bernd K. schrieb: > Im Speicher ist ein Array ein Array, alles andere ist Syntaxzucker. Der > Umgang damit (und der Zucker) ist in Pascal wie in C vollkommen > identisch. Dann ist man also in aktuellem Pascal nicht in der Lage, einem als Parameter übergebenen Array den zulässigen Indexbereich zu entlocken? Schade eigentlich, aber so tief stecke ich da nicht drin. Das hätte ich schon als Vorteil gesehen.
Bernd K. schrieb: > In Pascal funktionieren die Pointer, die Arrays > und die eckigen Klammern übrigens exakt genauso > wie in C, [...] Erwartest Du ganz im Ernst, dass man jemanden ernst nimmt, der solches Zeug schreibt? Ehrlich? Du suchst mit Sorgfalt eine Pascal-Variante, in der es geht, und behauptest dann: "In Pascal ist es genauso"? Nicht wirklich, oder? > Die Sprachen sind sich unter der Haube sehr ähnlich, Naja, da man im Laufe der Zeit mit Fleiss versucht hat, alle Restriktionen, die Wirth in die Sprache hineindefiniert hat, wieder herauszudefinieren und durch die C-typischen Hemdsärmligkeiten zu ersetzen, verwundert das nicht wirklich. Das ist aber genauso "intelligent" wie die Aussage: "BASIC ist objektorientiert". Sicherlich gibt es inzwischen BASIC-Varianten, auf die das zutrifft -- aber ist das die Kerneigenschaft, deretwegen BASIC bekannt geworden ist? > man macht die selben Sachen (nur schöner) und der > Compiler wird ähnlichen Code erzeugen. Es ist nur > ne intuitivere Syntax, mehr Typsicherheit und ein > gescheites Modulsystem, alles andere ist exakt wie C. Genau. Bis auf die fundamentalen Unterschiede ist es genau dasselbe. Super.
A. K. schrieb: > Dann ist man also in aktuellem Pascal nicht in der > Lage, einem als Parameter übergebenen Array den > zulässigen Indexbereich zu entlocken? Ging das jemals? Ich frage ganz im Ernst; meine Erinnerung an TurboPascal ist nicht mehr so taufrisch, und Delphi kenne ich nicht.
A. K. schrieb: > Dann ist man also in aktuellem Pascal nicht in der Lage, einem als > Parameter übergebenen Array den zulässigen Indexbereich zu entlocken? High(array, Low(array) und Length(array). A. K. schrieb: > Wer also dauernd auf den Pointern in C/C++ herumreitet, der sitzt > schlicht im falschen Zug. Ich schreibs nochmal ganz langsam: Es geht um Boolean Variablen und Bitpacked Arrays aus Booleans. Die kann ich definieren und benutzen, ohne dafür einen Pointer anfassen zu müssen. Auch in C.
Egon D. schrieb: > Du suchst mit Sorgfalt eine Pascal-Variante, in > der es geht Nein, ich habe die einzige Variante genommen die heute noch lebt und nicht irgendeine irrelevante Museumsleiche aus der Gründerzeit ausgegraben.
A. K. schrieb: > Dann ist man also in aktuellem Pascal nicht in der Lage, einem als > Parameter übergebenen Array den zulässigen Indexbereich zu entlocken? Die Funktion in meinem Beispiel erwartet einen Zeiger, kein Array.
Bernd K. schrieb: > Egon D. schrieb: >> Du suchst mit Sorgfalt eine Pascal-Variante, in >> der es geht > > Nein, ich habe die einzige Variante genommen die > heute noch lebt und nicht irgendeine irrelevante > Museumsleiche aus der Gründerzeit ausgegraben. Sage ich doch: Bis auf den Vornamen hat das zwar nix mehr mit Pascal zu tun, aber was tut man nicht alles, um Recht zu behalten...
Egon D. schrieb: > Sage ich doch: Bis auf den Vornamen hat das zwar nix > mehr mit Pascal zu tun, aber was tut man nicht alles, > um Recht zu behalten... Du hast laut eigenen Worten seit Turbopascal nichts mehr mit Pascal am Hut gehabt, bist also nicht qualifiziert darüber zu urteilen was Pascal heute ist oder was es (zum Glück) heute nicht mehr ist. Und was es "damals" war interessiert heute keinen mehr, dem muß man auch nicht nachtrauern, denn damals war es noch höchst unvollständig und damit praktisch unbrauchbar.
:
Bearbeitet durch User
Bernd K. schrieb: > Egon D. schrieb: >> Sage ich doch: Bis auf den Vornamen hat das zwar nix >> mehr mit Pascal zu tun, aber was tut man nicht alles, >> um Recht zu behalten... > > Du hast laut eigenen Worten seit Turbopascal nichts > mehr mit Pascal am Hut gehabt, Das waren nicht meine Worte. > bist also nicht qualifiziert Du beurteilst meine Qualifikation nicht. > darüber zu urteilen was Pascal heute ist oder was es > (zum Glück) heute nicht mehr ist. Pascal ist Pascal. TurboPascal ist TurboPascal. ObjectPascal ist ObjectPascal. Ziemlich einfach für jemanden, der sich genau ausdrücken WILL. > Und was es "damals" war interessiert heute keinen mehr, > dem muß man auch nicht nachtrauern, denn damals war es > noch höchst unvollständig und damit praktisch unbrauchbar. Ich weiss zwar nicht, woher Du das Recht nimmst, Herrn Professor Wirth als Stümper zu behandeln und als "Pascal" etwas völlig anderes zu bezeichnen, als er unter diesem Namen geschaffen hat -- aber ich muss ja nicht alles verstehen. Achtung vor fremder Leistung ist halt nicht jedermanns Sache.
Egon D. schrieb: > Sage ich doch: Bis auf den Vornamen hat das zwar nix > mehr mit Pascal zu tun, aber was tut man nicht alles, > um Recht zu behalten... Wenn du dich unbedingt an das Pascal von Wirth halten willst, dann landest du ganz schnell bei dem C von K&R. Beide sind heutzutage elefantenfrei.
Egon D. schrieb: > Das ist ... genauso "intelligent" wie die Aussage: > "BASIC ist objektorientiert". > Sicherlich gibt es inzwischen BASIC-Varianten, auf > die das zutrifft -- aber ist das die Kerneigenschaft, > deretwegen BASIC bekannt geworden ist? Objektorientierung kam erst Dekaden später in Mode, geschenkt ... Dennoch: du machst mich neugierig. Was glaubts du denn, was die Kerneigenschaft von BASIC ist, für die es bekannt geworden ist? Gepackte booleans (um mal kurz OnT zu werden) waren es wohl nicht. Ja, ich habe die Zeit erlebt. Und verdrängt. Zum Glück ...
Axel S. schrieb: > Was glaubts du denn, was die > Kerneigenschaft von BASIC ist, für die es bekannt geworden ist? Ich glaube, die ultimative Einfachheit. Das einfachste Hallo Welt, Lesbarkeit ohne jegliche Programmierkenntnisse, das Erfolgserlebnis (Lernkurve) wenn mit goto 10 das hallo fortlaufend ausgegeben wird. In Zeiten ohne Utube, Webseiten und "Computer" der Einstieg für Autodidakten. C war von und für Profis, Pascal für den Lehrbetrieb, Basic für die Bs in seinem Namen.
Anfangs war BASIC oft schlicht die einzige Sprache, die direkt verfügbar war. Die in 8kB ROM passte und schon mit 1kB RAM Ergebnisse brachte. Compiler waren auf solchen Systemen unpraktikabel. Die wurden erst praktisch nutzbar, als 64kB CP/M Systeme bezahlbar wurden. Da räumte Turbo Pascal ab, als es rauskam - das war eine Sensation aufgrund des vollintegrierten Ansatzes. C spielte auf solchen Systemen keine Rolle, das war Unis und deren Minicomputern vorbehalten. Im privaten Raum spielten parallel dazu natürlich Apples, C16/C64 und diverse Konkurrenten eine Rolle. Hauptsächlich in BASIC, denn das war schlicht dabei. Auch die ersten Generationen von IBM PCs und Clones hatten ein BASIC im ROM. Wer was anderes wollte, der musste zahlen oder klauen. Mit Eleganz und Schönheit, oder hohem Nutzwert der Sprache, hatte das also überhaupt nichts zu tun. BASIC war einfach dabei.
:
Bearbeitet durch User
Für mich sind die Kern-Eigenschaften von Basic: 1) War bei fast jedem Computer* mitgeliefert. 2) Bin ich auf Anhieb mit klar gekommen. 3) War in den Handbüchern und Bibliotheken gut dokumentiert. 4) Hatte (Anfangs) diese ätzenden Zeilennummern. *) PC, Amiga, Atari, C64, das sind die ersten Computer mit Tastatur und Bildschirm die ich kennengelernt habe. Später in der Schule wurde Pascal gelehrt, das gefiel mir besser weil es keine Zeilennummern mehr brauchte und man den Quelltext durch Einrückungen und Prozeduren/Funktionen ordentlich gestalten konnte. Mittlerweile kann Basic das aber auch.
Stefanus F. schrieb: > Mittlerweile kann Basic das aber auch. Ist halt nicht mehr ganz so basic wie damals. ;-)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.