Warum schreibt jeder über Standard-C-Typen?

Lesezeit: 7 Minuten

Benutzeravatar von Amomum
Amomum

Wenn Sie verwenden möchten Qtdu musst dich umarmen quint8, quint16 und so weiter.

Wenn Sie verwenden möchten GLibmüssen Sie begrüßen guint8, guint16 und so weiter.

An Linux es gibt u32, s16 und so weiter.

uC/OS definiert SINT32, UINT16 und so weiter.

Und wenn Sie eine Kombination dieser Dinge verwenden müssen, sollten Sie besser auf Ärger vorbereitet sein. Denn auf Ihrer Maschine u32 wird sein typedefd vorbei long und quint32 wird sein typedefd vorbei int und der Compiler werde reklamieren.

Warum tun das alle, wenn es das gibt <stdint.h>? Ist das eine Art Bibliothekstradition?

  • @Mehrdad in der Mikrocontroller-Programmierung können Sie alle möglichen Dinge haben. Auf AVR Mega’s zum Beispiel (und folglich auf dem berühmten Arduino) ist int 16 Bit. Das kann eine böse Überraschung sein. Meiner Meinung nach erfordert ‘unsigned short’ mehr Schreibaufwand. Und es hat mich immer traurig gemacht, ‘unsigned char’ für Byte Oktett zu verwenden. Unsignierter Charakter, wirklich?

    – Amum

    25. Juli 2016 um 0:42 Uhr


  • @Mehrdad Der Punkt ist, dass Sie sich nicht wirklich sicher sein können. Genau deshalb stdint.h wurde erfunden.

    – glglgl

    25. Juli 2016 um 9:07 Uhr

  • @glglgl: Hier ist eine andere Möglichkeit, das Problem zu betrachten: Stellst du nicht genau die falsche Frage? Wenn Sie auf mehrere Systeme abzielen, warum sollten Sie die Anzahl der Bits überhaupt willkürlich fest in den Code codieren? dh warum nicht einfach sagen sizeof(int) * CHAR_BIT (zum Beispiel) und das verwenden? Wenn dein int zu klein ist, um Ihren Bereich darzustellen (z. B. ein Array-Index), sollten Sie mit ziemlicher Sicherheit nicht verwenden int sowieso, aber so etwas wie size_t. Warum sollte int32 mehr Sinn machen? Nur bei der Kommunikation zwischen Systemen (z. B. Datei-/Netzwerkformat) macht eine feste Breite Sinn…

    – Benutzer541686

    25. Juli 2016 um 10:06 Uhr


  • @Mehrdad Nein. Manchmal habe ich Werte (z. B. von einem ADC oder was auch immer), die ich speichern muss. Ich weiß, dass sie 16 Bit breit sind. Das beste Ting ist also uint16_t (oder vielleicht sein fast oder least Variante). Mein Punkt ist: Diese Typen sind bequem zu verwenden und haben ihre Daseinsberechtigung.

    – glglgl

    25. Juli 2016 um 10:35 Uhr

  • @Mehrdad: Ich würde vorschlagen, dass Sie – vorausgesetzt, es scheint sich zu lohnen, Qualitätscode zu erstellen – Ihre eigene funktionale Typedefs-Bedeutung definieren sollten die Art und Weise, mit meiner API / dem Rest meines Codes zu interagierenund definieren Sie diese aus technischen Gründen in Form von „technischen“ Typedefs wie size_t und/oder uint64_t.

    – PJTrail

    1. August 2016 um 12:23 Uhr


Benutzeravatar von Edward Karak
Eduard Karak

stdint.h gab es noch nicht, als diese Bibliotheken entwickelt wurden. Also hat jede Bibliothek ihre eigene gemacht typedefs.

  • Und okay, ich nehme an, das Fehlen von stdint.h ist ein guter Grund, aber warum sind diese Typedefs auch heute noch über int, long und so weiter und nicht über stdint-Typen? Es würde sie zumindest austauschbar machen

    – Amum

    24. Juli 2016 um 13:14 Uhr

  • @Amomum “Warum hat Glib (das unter Linux entwickelt wurde) keine Linux-Typedefs verwendet?” Während die “Heimatbasis” von glib sicherlich Linux ist, ist es ebenso sicher eine portable Bibliothek. Das Definieren eigener Typen gewährleistet die Portabilität: Man muss nur einen winzigen Header anpassen, der die Bibliothekstypen auf die richtigen jeweiligen Zielplattformtypen abstimmt.

    – Peter – Setzen Sie Monica wieder ein

    24. Juli 2016 um 13:27 Uhr


  • @Amoma Warum Glib (das unter Linux entwickelt wurde) … Nein, war es nicht. Glib wurde erstellt Weg vor dem Linux-Kernel.

    – andy256

    25. Juli 2016 um 5:01 Uhr

  • @andy256 “GLib” ist nicht die Abkürzung für “glibc”. Es ist eine Bibliothek, die von gtk abgezweigt ist. Es ist nicht älter als Linux.

    Benutzer2404501

    25. Juli 2016 um 12:05 Uhr

  • @andy256: Glib ist 1998, Linux ist 1991. IOW, GLib wurde so erstellt nach Linux.

    – MSalter

    25. Juli 2016 um 13:18 Uhr

Für die älteren Bibliotheken ist dies erforderlich, da der betreffende Header (stdint.h) gab es nicht.

Es gibt jedoch immer noch ein Problem: Diese Typen (uint64_t und andere) sind eine optionale Funktion im Standard. Daher wird eine konforme Implementierung möglicherweise nicht mit ihnen ausgeliefert – und zwingt Bibliotheken daher, sie auch heute noch aufzunehmen.

  • Das uintN_t Typen sind optional, aber die uint_leastN_t und uint_fastN_t Typen sind es nicht.

    – Kusalananda

    24. Juli 2016 um 13:29 Uhr

  • @Kusalananda: Leider sind diese von begrenztem Nutzen.

    – Leichtigkeitsrennen im Orbit

    24. Juli 2016 um 14:42 Uhr


  • Der Grund dafür, dass sie optional sind, liegt natürlich darin, dass Ihnen dies nicht garantiert werden kann sind Integer-Typen mit genau dieser Anzahl von Bits. C unterstützt immer noch Architekturen mit ziemlich ungeraden ganzzahligen Größen.

    – Celtschk

    24. Juli 2016 um 16:04 Uhr

  • @LightnessRacesinOrbit: Inwiefern sind sie von begrenztem Nutzen? Ich muss zugeben, dass ich abgesehen von Hardwareschnittstellen nicht verstehe, warum Sie eine genaue Anzahl von Bits und nicht nur ein Minimum benötigen, um sicherzustellen, dass alle Ihre Werte passen.

    – Celtschk

    24. Juli 2016 um 16:07 Uhr

  • @Amomum Die Typedefs sind erforderlich, wenn die Implementierung Typen hat, die die Anforderungen erfüllen: “Wenn jedoch eine Implementierung Integer-Typen mit Breiten von 8, 16, 32 oder 64 Bits, ohne Füllbits und (für die vorzeichenbehafteten Typen) mit einer Zweierkomplementdarstellung bereitstellt, es soll die entsprechenden Typedef-Namen definieren.” (Zitat aus N1570, 7.20.1.1 “Integertypen mit exakter Breite”) Wenn die Standardbibliothek sie also nicht hat, könnte eine Bibliothek eines Drittanbieters dies anscheinend auch nicht.

    – Eric M. Schmidt

    25. Juli 2016 um 0:54 Uhr


stdint.h ist seit 1999 standardisiert. Es ist wahrscheinlicher, dass viele Anwendungen (effektiv Alias-) Typen definieren, um eine teilweise Unabhängigkeit von der zugrunde liegenden Maschinenarchitektur aufrechtzuerhalten.

Sie geben Entwicklern die Gewissheit, dass die in ihrer Anwendung verwendeten Typen ihren projektspezifischen Annahmen zum Verhalten entsprechen, die möglicherweise weder dem Sprachstandard noch der Compiler-Implementierung entsprechen.

Die Praxis spiegelt sich in der Objektorientierung wider Fassade Entwurfsmuster und wird häufig von Entwicklern missbraucht, die ausnahmslos Wrapper-Klassen für alle importierten Bibliotheken schreiben.

Als Compiler viel weniger Standard waren und Maschinenarchitekturen von 16-Bit abweichen konnten, 18-bit durch 36-Bit Bei Großrechnern mit Wortlänge war dies eine viel größere Überlegung. Diese Praxis ist jetzt in einer Welt, die auf eingebettete 32-Bit-ARM-Systeme konvergiert, viel weniger relevant. Es bleibt ein Problem für Low-End-Mikrocontroller mit seltsam Speicher Karten.

  • Gewährt, stdint.h ist seit 1999 standardisiert, aber seit wann ist es in der Praxis verfügbar? Die Menschen zögern, neue Standards zu implementieren und zu übernehmen, und während dieser langen Übergangszeit sind alte Methoden immer noch ein Muss.

    – Siyuan Ren

    25. Juli 2016 um 3:07 Uhr


  • Eine böse Gotcha mit stdint.h geht das auch auf Plattformen wo zB long und int32_t die gleiche Größe und Darstellung haben, gibt es keine Anforderung, dass ein Casting an int32_t* zu long* ergibt einen Zeiger, der zuverlässig auf a zugreifen kann int32_t. Ich kann nicht glauben, dass die Autoren des Standards es für offensichtlich hielten, dass Layout-kompatible Typen Alias-kompatibel sein sollten, aber da sie sich nicht die Mühe gemacht haben, dies zu sagen, glauben die Autoren von gcc und IIRC Clang, dass die Sprache sogar durch Ignorieren von Aliasing verbessert werden würde in Fällen, in denen es offensichtlich ist.

    – Superkatze

    25. Juli 2016 um 15:49 Uhr

  • @supercat – das ist es wahrscheinlich wert, als Erratum beim C-Komitee eingereicht zu werden … weil das so ist grundlos dummum es milde auszudrücken

    – LThode

    25. Juli 2016 um 16:27 Uhr

  • @LThode: Damit das C-Komitee dies als Fehler anerkennt, müsste es das Verhalten von clang und gcc offiziell als stumpf erklären. Glaubst du, das wird passieren? Das Beste, was man sich erhoffen könnte (und meiner Meinung nach der logische Weg, um fortzufahren), wäre, Wege zu definieren, wie Programme “Aliasing-Modi” angeben können. Wenn ein Programm angibt, dass es sehr strenge Aliasing-Regeln akzeptieren kann, könnte ein Compiler dies verwenden, um Optimierungen zu ermöglichen, die über das hinausgehen, was derzeit möglich ist. Wenn ein Programm angibt, dass es Regeln benötigt, die etwas programmiererfreundlicher sind als die jetzigen…

    – Superkatze

    25. Juli 2016 um 16:47 Uhr

  • …aber immer noch viele nützliche Optimierungen ermöglichen würde, dann könnte ein Compiler Code generieren, der viel effizienter ist, als dies mit möglich wäre -fno-strict-alias, was aber eigentlich noch funktionieren würde. Selbst wenn es keine vorhandene Codebasis gäbe, könnte kein einzelnes Regelwerk das optimale Gleichgewicht zwischen Optimierung und Semantik für alle Anwendungen finden, da unterschiedliche Anwendungen unterschiedliche Anforderungen haben. Fügen Sie die vorhandene Codebasis hinzu und die Notwendigkeit verschiedener Modi sollte klar sein.

    – Superkatze

    25. Juli 2016 um 16:49 Uhr

Sie haben also die Möglichkeit, char in int zu typedef.

Ein „Codierungshorror“ erwähnte, dass der Header eines Unternehmens einen Punkt hatte, an dem ein Programmierer einen booleschen Wert haben wollte, und ein Zeichen der logische native Typ für den Job war, und so schrieb er typedef bool char. Dann fand später jemand eine ganze Zahl als die logischste Wahl und schrieb typedef bool int. Das Ergebnis, Jahre vor Unicode, war virtuell typedef char int.

Ziemlich viel vorausschauendes Denken, Vorwärtskompatibilität, denke ich.

1421370cookie-checkWarum schreibt jeder über Standard-C-Typen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy