Ich habe Kopfschmerzen, die hier Probleme verursachen.
Im Grunde versuche ich, eine Bibliothek mit verschiedenen Arduino-Systemen kompatibel zu machen (keine Arduino-Frage).
Ich habe eine Situation, in der Typen nicht mehr übereinstimmen, da in int
nicht mehr der identische Typ fester Breite entspricht. In der begrenzten Umgebung (keine stdlib und so) habe ich meine eigenen Typmerkmalsklassen für die Features geschrieben, die ich brauche.
Mit GCC 4.8.1 (avr) & amp; Extensa-1x106-GCC (ESP8266), aber nicht in GCC 4.8.3 (SAM, SAMD-Kerne).
Grundsätzlich habe ich meinen Code durchgeknallt, um das Problem in diesem sehr grundlegenden Code zu zeigen ( int
wird bestätigt, um 4 Bytes auf den fehlerhaften 32-Bit-Plattform-Compilern zu haben):
Sie können hier eine 'normale' C ++ - Implementierung anzeigen (oben ist eine grundlegende Implementierung für die Verwendung in der Arduino IDE): Ссылка
Übrigens wird das statische Assert auch nicht im Compiler cpp.sh ausgelöst.
Ist 4.8.1 falsch, dh int
und int32_t
sollten als unterschiedliche Typen betrachtet werden. Oder ist 4.8.3 falsch und sie sollten äquivalent sein, wenn sie durch die Implementierung gleich groß sind.
Ich habe den folgenden Code verwendet, um einen beliebigen Integer-Typ zu erkennen. Dort habe ich ursprünglich meinen Fehler gefunden.
%Vor% Ich kann natürlich ändern, um nach char
, int
, long
usw. zu suchen. Aber es wird immer noch nach allen festen Breitenvariationen und höchstwahrscheinlich den int_fastX_t
und int_leastX_t
Typen suchen müssen , die wie eine superredundante Methode erscheint, um maximale Benutzerfreundlichkeit sicherzustellen.
Irgendwelche Ideen?
Prost, ich schätze jede Eingabe!
Dies wird durch den C-Standard geregelt; das C ++ - man erbt nur das Verhalten durch explizite Referenz.
Was der C-Standard sagt, ist:
Wenn int32_t
definiert ist, bezieht es sich auf eine vorzeichenbehaftete 32-Bit Zweierkomplement-Ganzzahl.
Wenn die Implementierung einen vorzeichenbehafteten 32-Bit-2er-Komplement-Integer-Typ bereitstellt, muss sie den Typdef int32_t
angeben, der darauf verweist.
Nirgends heißt es, dass dieser vorzeichenbehaftete Integer-Typ mit 32-Bit-Zweierkomplement int
sein muss. Technisch gesehen ist es, selbst wenn int
ist ein 32-Bit-2er-Komplement-Integer-Typ, durchaus möglich, dass die Implementierung auch einen eigenen 32-Bit-2er-Komplement-Integer-Typ vorgibt und int32_t
definiert beziehen sich auf diesen anderen Typ.
Ich fürchte, die einzige vollständig generische Lösung bestünde darin, alle grundlegenden Typen, Typen mit fester Breite, Typen mit minimaler Breite und Typen mit kurzer Mindestbreite aufzulisten.
Für etwas weniger Beängstigendes sollte es möglich sein, die Dokumentation der Toolchains, die Sie unterstützen möchten, zu überprüfen, um herauszufinden, welche Typen sie bereitstellen und wie sie sie benennen. Wenn dieser Satz von "Toolchains, die Sie unterstützen möchten" unbegrenzt ist, glaube ich nicht, dass es einen einfacheren Ausweg gibt.
Aus dem C11-Standard 7.20.1.1 (1)
Der typedef-Name intN_t bezeichnet einen ganzzahligen Typ mit Vorzeichen mit der Breite N, ohne Auffüllung Bits und eine Zweierkomplementdarstellung. So bezeichnet int8_t ein solches signed Integer-Typ mit einer Breite von genau 8 Bit.
So int32_t
ist eine vorzeichenbehaftete Ganzzahl, die genau 32 Bit breit ist.
Ein int
though ist definiert als sizeof(int)
ist größer oder gleich einem char
(C ++ 14 3.9.1 (2)) und ein signed int muss in der Lage sein, [-32767, 32767]
( C11 5.2.4.2.1). Dieser Bereich ist eigentlich 16 Bit.
Also kann ein int
niemals einem intN_t
entsprechen, da ein intN_t
ein implementierungsdefinierter Typ sein kann, der von einem Standardtyp getrennt ist.