Forum: Compiler & IDEs uint32_t wo kommt das her?


von Hein Mück aus Bremerhaven (Gast)


Lesenswert?

Hi, ich hab im Forum hier gelernt, das man anstelle von unsigned long 
int auch uint32_t schreiben kann. Unter Atmel Studio 6.1 geht das auch, 
aber der Realview von Keil uV3 kennt das nicht. Was muss ich dem 
Realview eingeben, damit er das auch kennt? Woher kennt der GCC 
uint32_t? Ist das über haupt C konform?!

von (prx) A. K. (prx)


Lesenswert?

Gibts garantiert auch bei Keil, weil Standard:
#include <stdint.h>

: Bearbeitet durch User
von Dr. Sommer (Gast)


Lesenswert?

Hein Mück aus Bremerhaven schrieb:
> Woher kennt der GCC uint32_t?
Aus der <stdint.h> die du inkludieren musst.

> Ist das über haupt C konform?!
Ja.

von Hein Mück aus Bremerhaven (Gast)


Lesenswert?

Bin mir nicht sicher, ob ich die stdint.h includiert habe. Muss mal am 
Montag schauen..

von (prx) A. K. (prx)


Lesenswert?

Bei Atmel kriegst du die als Nebeneffekt anderer Includes meist 
automatisch mit rein. Bei Keil möglicherweise nicht.

von Wolfgang (Gast)


Lesenswert?

Hein Mück aus Bremerhaven schrieb:
> Ist das über haupt C konform?!

Warum sollte es nicht C konform sein? Wer will dir verbieten in deinen 
Code ein
1
#define uint32_t unsigned long int
einzubauen.

von DirkB (Gast)


Lesenswert?

Hein Mück aus Bremerhaven schrieb:
>  Ist das über haupt C konform?!

C kennt verschiedenen Standards.
stdint.h ist mit C99 gekommen.

Kann man auch auf Wikipedia nachlesen.

C89 sollten alle Compiler beherschen. Darum gilt das als kleinster 
geimeinsamer Nenner und manche benutzen es ausschließlich.
(Das liegt auch daran, dass Microsoft in seinen Compilern keinen neueren 
Standard unterstützt.)

von Rolf M. (rmagnus)


Lesenswert?

DirkB schrieb:
> Hein Mück aus Bremerhaven schrieb:
>>  Ist das über haupt C konform?!
>
> C kennt verschiedenen Standards.

Eigentlich nur einen - den aktuellsten. Mit erscheinen dessen wird die 
Vorgänger-Version für ungültig erklärt und ist nicht mehr erhältlich.

> C89 sollten alle Compiler beherschen. Darum gilt das als kleinster
> geimeinsamer Nenner und manche benutzen es ausschließlich.
> (Das liegt auch daran, dass Microsoft in seinen Compilern keinen neueren
> Standard unterstützt.)

Nicht nur Microsoft, auch andere Compiler-Hersteller sind da leider 
teilweise auf einem Stand von vor über einem Viertel Jahrundert stehen 
geblieben. Microsoft ist aber das prominenteste Beispiel.

von meckerziege (Gast)


Lesenswert?

Hein Mück aus Bremerhaven schrieb:
> das man anstelle von unsigned long
> int auch uint32_t schreiben kann

Der Vollständigkeit halber sei angemerkt, dass ein "unsigned long int" 
nur unter bestimmen umständen einem uint32_t gleicht.
Beispiel: Auf nem 64-bit Rechner und GCC, ist int 32 bit breit und ein 
long int 64-bit breit!

von (prx) A. K. (prx)


Lesenswert?

meckerziege schrieb:
> Beispiel: Auf nem 64-bit Rechner und GCC, ist int 32 bit breit und ein
> long int 64-bit breit!

In Linux korrekt, in Windows nicht:
http://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

Um das noch weiter zu vervollständigen: Darum gibt es die 
[u]int*_t-Typedefs. Sie garantieren eine fixe Breite im Gegensatz zu den 
klassischen Integertypen. Die sind aber eigentlich dafür gedacht, wenn 
es wichtig ist, daß die Größe exakt stimmt. Diese Typedefs existieren 
auch nur, wenn der Compiler für die Zielplattform entsprechend breite 
Integertypen überhaupt anbietet. Außerdem kann es je nach Plattform 
sein, daß ein größerer Typ effizienter wäre. Auf 32-Bit-Plattformen kann 
es z.B. durchaus sein, daß die Nutzung von 16-Bit-Typen zu etwas 
größerem und/oder langsamerem Code führt.
Es gibt deshalb auch noch uint_least32_t, was dem kleinsten verfügbaren 
Typ mit mindestens 32 Bit entspricht, sowie uint_fast32_t, das dann der 
schnellsten Typ mit mindestsn 32 Bit ist.
Sofern man also nicht gerade mit Hardware-Registern arbeitet oder einem 
das Überlaufverhalten des 32-Bit-Typs wichtig ist, gibt es eigentlich 
keinen wirklichen Grund, uint32_t zu nutzen.

von Peter D. (peda)


Lesenswert?

Rolf Magnus schrieb:
> Sofern man also nicht gerade mit Hardware-Registern arbeitet oder einem
> das Überlaufverhalten des 32-Bit-Typs wichtig ist, gibt es eigentlich
> keinen wirklichen Grund, uint32_t zu nutzen.

Der 32Bit Überlauf ist selten der Grund.

int kann auch 16 Bit sein, long int auch 64 Bit.
Mit uint32_t ist dagegen das Format nicht zu klein und nicht unnötig 
groß.

von WehOhWeh (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Der 32Bit Überlauf ist selten der Grund.
>
> int kann auch 16 Bit sein, long int auch 64 Bit.
> Mit uint32_t ist dagegen das Format nicht zu klein und nicht unnötig
> groß.

Außerdem mach die Verwendung der neueren Typen den Code portabler.

Verwendet man die normalen Typen (int usw.)  kann es passieren, dass man 
den Code duch einen anderen Compiler jagt und dann plötzlich Probleme 
durch Überläufe und ähnlichen Kram bekommt.
Das betrifft insbesondere die µConrtroller, eben weil 8bitter, 16bitter 
und 32bitter unterwegs sind.

Ich hatte das schon bei der Portierung eines Programms für einen PIC32 
auf einen PIC12.

Die Typen mit Angabe der Breite sind einfach sauberer.

von (prx) A. K. (prx)


Lesenswert?

WehOhWeh schrieb:
> Ich hatte das schon bei der Portierung eines Programms für einen PIC32
> auf einen PIC12.

Wobei man in solchen Fällen für lokale Variablen die XXX_fastYYY_t Typen 
verwenden sollte, denn eine Verwendung von Registern mit weniger als 32 
Bit Breite ist für die PIC32 eine ziemliche Zumutung. Ein uint_fast8_t 
ist auf dem PIC12 8 Bit breit, auf dem PIC32 32 Bits, und passt daher 
beiden. Ein uint8_t hingegen ist auch auf dem PIC32 im Register nur 8 
Bits breit, was zusätzlichen Aufwand für Bitreduktion zur Folge haben 
kann.

: Bearbeitet durch User
von Rolf Magnus (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Rolf Magnus schrieb:
>> Sofern man also nicht gerade mit Hardware-Registern arbeitet oder einem
>> das Überlaufverhalten des 32-Bit-Typs wichtig ist, gibt es eigentlich
>> keinen wirklichen Grund, uint32_t zu nutzen.
>
> Der 32Bit Überlauf ist selten der Grund.

Eben, deshalb ist der Typ auch deutlich seltener sinnvoll, als er 
tatsächlich eingesetzt wird.

> int kann auch 16 Bit sein, long int auch 64 Bit.
> Mit uint32_t ist dagegen das Format nicht zu klein und nicht unnötig
> groß.

von Rolf Magnus (Gast)


Lesenswert?

Ups, wo ist denn der Rest meines Postings geblieben? Also nochmal:

Peter Dannegger schrieb:
> int kann auch 16 Bit sein, long int auch 64 Bit.
> Mit uint32_t ist dagegen das Format nicht zu klein und nicht unnötig
> groß.

Genau dafür ist uint_least32_t gedacht. Und wenn die Geschwindigkeit 
wichtiger ist als die Größe, nimmt man uint_fast32_t. So ist die Angabe 
der exakten Größe mit uint32_t eben nur noch in den zwei Fällen nötig, 
die ich angegeben habe: Hardware-Register und Überlaufverhalten.

von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


Lesenswert?

Rolf Magnus schrieb:
> So ist die Angabe der exakten Größe mit uint32_t eben nur noch in den
> zwei Fällen nötig, die ich angegeben habe: Hardware-Register und
> Überlaufverhalten.

Das ist falsch. Ein weiterer, durchaus sehr wichtiger Anwendungsfall ist 
die Definition von Strukturen mit festen Größenangaben, z.B. bei Datei- 
oder Kommunikationsprotokollen.

Hierbei muss man sich aber ggf. auch auf ein bestimmtes Padding des 
Compilers verlassen bzw. dieses per Direktive steuern.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Andreas Schweigstill schrieb:
> Hierbei muss man sich aber ggf. auch auf ein bestimmtes Padding des
> Compilers verlassen bzw. dieses per Direktive steuern.

Damit ist man sofort nicht mehr portabel, denn der Standard sieht eine
derartige Möglichkeit nicht vor.  Padding liegt immer im Ermessen des
Compilers.

Außerdem kann es dadurch zu Problemen mit unaligned access kommen
(genau darum erfolgt ja normalerweise auch das Padding, das ist ja kein
Selbstzweck).

Byteorder-Probleme kommen noch hinzu.

von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


Lesenswert?

Jörg Wunsch schrieb:
> Damit ist man sofort nicht mehr portabel, denn der Standard sieht eine
> derartige Möglichkeit nicht vor.

Das ist durchaus korrekt. Rolf hat aber als andere Anwendungsmöglichkeit 
Hardwarezugriffe aufgeführt. Diese sind noch weniger portabel und ebenso 
wenig durch den Standard abgedeckt.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Andreas Schweigstill schrieb:
> Diese sind noch weniger portabel und ebenso wenig durch den Standard
> abgedeckt.

Allerdings spielt im Allgemeinen bei Hardwarezugriffen die
Portabilität nur eine untergeordnete Rolle (läuft dann eh' nur auf
der Plattform, und die Zugriffe abstrahiert man für gewöhnlich in
einem passenden Layer).

Kommunikationsprotokolle dagegen möchte man ja vielleicht doch ein
wenig portabel haben, denn der Sinn der Kommunikation ist es meist
nicht, Selbstgespräche zu führen. ;-)

von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


Lesenswert?

Jörg Wunsch schrieb:
> Kommunikationsprotokolle dagegen möchte man ja vielleicht doch ein
> wenig portabel haben, denn der Sinn der Kommunikation ist es meist
> nicht, Selbstgespräche zu führen. ;-)

Das Protokoll muss portabel sein, nicht dessen Implementierung. Und wenn 
wir schon dabei sind: schau doch einmal in diverse TCP/IP-Stacks. Dort 
werden die Header häufig auch über Strukturen definiert bzw. zerlegt.

Dabei gibt es aber in der Tat manchmal massive Alignmentprobleme, wie 
ich vor längerer Zeit einmal bei einem teuer (>20kEUR) TCP/IP-Stack 
erfahren durfte. Insbesondere der 14 Byte große Ethernet-Header führt zu 
einem schönen Versatz, nämlich wenn der Compiler davon ausgeht, dass die 
Struktur, die den IP-Header bestimmt, an einer 4-Byte-Grenze beginnt...

von Jay (Gast)


Lesenswert?

Rolf Magnus schrieb:
> DirkB schrieb:
>> Hein Mück aus Bremerhaven schrieb:
>>>  Ist das über haupt C konform?!
>>
>> C kennt verschiedenen Standards.
>
> Eigentlich nur einen - den aktuellsten. Mit erscheinen dessen wird die
> Vorgänger-Version für ungültig erklärt und ist nicht mehr erhältlich.

Die ungültigen Vorgängerversionen kann man durchaus noch kaufen. 
Allerdings macht es einem die ISO ein bisschen schwer. Alte Versionen 
gibt es nur noch auf Papier und auf Anfrage.

Die Gültigkeit liegt sowieso im Auge des Betrachters. Wenn man sich zum 
Beispiel in einem Vertrag auf eine Version geeinigt hat, dann ist genau 
diese für die Vertragserfüllung gültig.

von Rolf Magnus (Gast)


Lesenswert?

Andreas Schweigstill schrieb:
> Jörg Wunsch schrieb:
>> Kommunikationsprotokolle dagegen möchte man ja vielleicht doch ein
>> wenig portabel haben, denn der Sinn der Kommunikation ist es meist
>> nicht, Selbstgespräche zu führen. ;-)
>
> Das Protokoll muss portabel sein, nicht dessen Implementierung.

Wenn man die nicht für jede Zielplattform neu schreiben will, ist es 
schon sinnvoll, sie auch portabel zu gestalten.

> Insbesondere der 14 Byte große Ethernet-Header führt zu einem schönen
> Versatz, nämlich wenn der Compiler davon ausgeht, dass die Struktur, die
> den IP-Header bestimmt, an einer 4-Byte-Grenze beginnt...

Ich erinnere mich da an Performance-Probleme mit bestimmten 
billig-Ethernet-Karten, weil aufgrund dieses Alignment-Problems kein DMA 
benutzt werden konnte und empfangene Pakete immer "von Hand" in einen 
Speicherblock mit richtigem Alignment umkopiert werden mussten.

Jay schrieb:
> Die ungültigen Vorgängerversionen kann man durchaus noch kaufen.
> Allerdings macht es einem die ISO ein bisschen schwer. Alte Versionen
> gibt es nur noch auf Papier und auf Anfrage.

Ah, ok. Das war mir nicht bekannt. Ich hatte nur gesehen, daß sie im 
Webshop nicht mehr verfügbar sind.

> Die Gültigkeit liegt sowieso im Auge des Betrachters.

Jede neue Version der ISO-Norm sagt gleich auf der ersten Seite, dass 
sie mit ihrem Erscheinen alle vorhergehenden Versionen komplett ersetzt 
und für ungültig erklärt.

> Wenn man sich zum Beispiel in einem Vertrag auf eine Version geeinigt
> hat, dann ist genau diese für die Vertragserfüllung gültig.

Das schon. Der Vertrag wäre dann quasi der Compiler, den man gekauft 
hat, bevor die neue Version rausgekommen ist. Daß dieser alte Compiler 
nicht plötzlich die neue Version unterstüzt, ist ja klar. Neue Compiler 
sollten das aber eigentlich schon. Ist ja bei anderen ISO-Normen auch 
so.
Meiner Meinung nach kann sich eine aktuelle Version eines Compilers 
nicht ISO- (oder ANSI-) C-konform schimpfen, wenn er nicht die aktuelle 
Version unterstützt.

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
Noch kein Account? Hier anmelden.