Wenn int kein int (intX_t) ist

8

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):

%Vor%

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!

    
Chris A 28.09.2015, 11:42
quelle

2 Antworten

4

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.

    
Angew 28.09.2015, 12:00
quelle
0

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.

    
NathanOliver 28.09.2015 12:01
quelle

Tags und Links