Forum: Mikrocontroller und Digitale Elektronik implementierung datentypen


von Chandler B. (chandler)


Lesenswert?

Hallo,
wie sind eigentlich die standard datentypen implementiert?

Wenn ich in die stdint.h gucke sehe ich nur ein mapping zu den 
Datentypen welche ich verwende
1
typedef signed char    int8_t;
2
typedef unsigned char    uint8_t;
3
typedef short      int16_t;
4
typedef unsigned short    uint16_t;
5
typedef int      int32_t;
6
typedef unsigned    uint32_t;
7
typedef long long    int64_t;
8
typedef unsigned long long  uint64_t;
aber wie ist z.B. unsigned long long implementiert?
Diesen kann ich ja auch auf einem AVR (8Bit) benzutzen.

Wäre es möglich so auch noch größere Datentypen zu implementieren (z.B. 
uint128_t) ?

von EAF (Gast)


Lesenswert?

Chandler B. schrieb:
> Wäre es möglich so auch noch größere Datentypen zu implementieren (z.B.
> uint128_t) ?
Für die nativen Typen gibt es fertige Funktionen und Operatoren.

Für eigene Typen muss man das alles selber bauen.
C++ bietet die Chance, in C sind da mehr Kompromisse nötig.

Chandler B. schrieb:
> aber wie ist z.B. unsigned long long implementiert?
In der Sprachdefinition selber, also im Compiler.

von Maxe (Gast)


Lesenswert?

Chandler B. schrieb:
> aber wie ist z.B. unsigned long long implementiert?
> Diesen kann ich ja auch auf einem AVR (8Bit) benzutzen.

Der Compiler muss fuer die Datentypen speziellen Code generieren, das 
beginnt damit, dass beim Laden aus dem RAM die einzelnen Byte in 
verschiedene Register geladen werden. Dann muss je nach Operation 
bestimmter Code erzeugt werden. Bspw. fuer Additionen gibt es das 
Carry-Flag, zuerst werden die beiden niederwertigen Byte addiert, kommt 
es zum Ueberlauf bei der Addition dann setzt die CPU das Carryflag, 
welches bei der Addition der naechsten beiden Byte dann beruecksichtigt 
wird (Uebertrag). Oder beim Vergleich zweier Zahlen muessen alle Bytes 
verglichen werden, ja nach Art des Vergleichs (kleiner/groesser/gleich) 
eben unterschiedlich. Der Compiler nimmt einem da viel Arbeit ab. 
Verursacht aber bei grossen Datentypen auch einiges an Code.

von Oliver S. (oliverso)


Lesenswert?

Chandler B. schrieb:
> aber wie ist z.B. unsigned long long implementiert?
> Diesen kann ich ja auch auf einem AVR (8Bit) benzutzen.

Na ja, "implementiert" sind die so, wie es in der Doku zum Compiler 
steht. In den allermeisten Fällen als benötigte Anzahl Bytes 
hintereinander, und dann halt big oder little endian.

Chandler B. schrieb:
> Wäre es möglich so auch noch größere Datentypen zu implementieren (z.B.
> uint128_t) ?

Es gibt Compiler-Versionen, die 128-Byte Datentypen unterstützen. 
Allerdings nicht für AVR.

Oliver

von W.S. (Gast)


Lesenswert?

Chandler B. schrieb:
> typedef unsigned char ...

In der Programmiersprache C gibt es Variablen-Typen wie char, int und 
float. Solche Dinge wie signed oder unsigned sowie short oder long sind 
Attribute, die man zusätzlich angeben kann. Und genau DAS ist es, was 
der Compiler eigentlich versteht. Alle solchen "Datentypen" wie uint16_t 
oder so sind lediglich Alias-Namen für die eigentlichen Typen. Man 
könnte sowas auch 'ottokar' oder 'karlheinz' nennen:
1
typedef unsigned char ottokar;
aber das macht keiner, weil es nicht technisch genug klingt.

Das ist eigentlich alles.

W.S.

von Irgend W. (Firma: egal) (irgendwer)


Lesenswert?

Oliver S. schrieb:
> Es gibt Compiler-Versionen, die 128-Byte Datentypen unterstützen.
> Allerdings nicht für AVR.

Wie kommst du auf AVR? Ich kenne keine wo int 32Bit ist und 64Bit werden 
dort meines wissens nach auch nicht unterstützt.

Chandler B. schrieb:
> wie sind eigentlich die standard datentypen implementiert?
>
> Wenn ich in die stdint.h gucke sehe ich nur ein mapping zu den
> Datentypen welche ich verwende

Implementiert, wie schon erwähnt im Programmcode des Compilers.
Das Interessante an den Typen die in stdint.h definiert sind, ist das 
sie eben von verwendetem Compiler und CPU-Architektur weitestgehend 
unabhängig sind. Vorausgesetzt das ganze unterstützt was Vergleichbares. 
Wenn nein, merkt man an der Fehlermeldung aber ganz schnell das es 
diesen Type nicht gibt. 128Bit wirst du nur auf 64Bit Architekturen 
finden.
Bestes Beispiel ist "int", der ist je nach System 16Bit, 32Bit oder 
64Bit. Ein int32_t ist auch auf einer 8bit-Gurke 32Bit breit und eben 
nicht 16Bit wie int.

- 
https://stackoverflow.com/questions/16088282/is-there-a-128-bit-integer-in-gcc

von W.S. (Gast)


Lesenswert?

Irgend W. schrieb:
> Das Interessante an den Typen die in stdint.h definiert sind, ist das
> sie eben von verwendetem Compiler und CPU-Architektur weitestgehend
> unabhängig sind.

Nein, genau SO HERUM ist es eben nicht. Solche Dinge wie all das, was in 
stdint.h definiert ist, muß mittels der zu dem jeweiligen Compiler 
passenden stdint.h in die eigentlichen Grundtypen zurückübersetzt 
werden, damit aus Sicht des Anwenders dieser Toolchain eine 
plattformunabhängiger Datentyp erzielt werden kann. Genau deshalb ist 
das eben compiler- bzw. plattformspezifisch und keinesfalls unabhängig.

Also nochmal: die Datentypen bei C sind schwammig definiert (z.B. keine 
fest definerten Längen) und die Präzisierung mit Attributen (long oder 
short, signed oder unsigned etc.) ist den typischen C-Programmierern zu 
lästig hinzuschreiben, weswegen in der Vergangenheit viele sich eigene 
Kürzel geschaffen haben: U8 oder U16 (jedoch m.W. nirgends 'ottokar').

Das hatte nun ein Gremium aufgegriffen und gesagt: "wir wollen alle eben 
diese Datentypen umbenennen und dabei uniformierte Bezeichner wählen, so 
daß bei der Verwendung durch den Programmierer auf allen Maschinen ein 
zum vom Programmierer gewünschten Zweck der jeweils passende eigentliche 
Datentyp je nach Compiler verwendet werden soll. Am Compiler oder der 
Sprache C selbst findet keine Änderung statt."

Anstatt also die vom Compiler verstandenen Datentypen zu reformieren, 
wurde eine stdint.h vorgeschlagen, die als Übersetzungsmedium zum 
Compiler hin fungieren soll. Diese Datei ist compilerspezifisch. Rein 
theoretisch könnte man daher seine Datentypen auch ottokar oder 
karlheinz nennen. Das ist alles nur eine Wortersetzungs-Frage letztlich.

W.S.

von Blechbieger (Gast)


Lesenswert?

W.S. schrieb:
> Diese Datei ist compilerspezifisch

Genau genommen Compiler & Architektur spezifisch. Teilweise sogar noch 
das ABI.

Hier mal vom SCC für Z80
1
typedef signed char int8_t;
2
typedef int int16_t;
3
typedef long int32_t;
4
typedef long long int64_t;
5
6
typedef unsigned char uint8_t;
7
typedef unsigned uint16_t;
8
typedef unsigned long uint32_t;
9
typedef unsigned long long uint64_t;

von Rolf M. (rmagnus)


Lesenswert?

W.S. schrieb:
> Irgend W. schrieb:
>> Das Interessante an den Typen die in stdint.h definiert sind, ist das
>> sie eben von verwendetem Compiler und CPU-Architektur weitestgehend
>> unabhängig sind.
>
> Nein, genau SO HERUM ist es eben nicht. Solche Dinge wie all das, was in
> stdint.h definiert ist, muß mittels der zu dem jeweiligen Compiler
> passenden stdint.h in die eigentlichen Grundtypen zurückübersetzt
> werden, damit aus Sicht des Anwenders dieser Toolchain eine
> plattformunabhängiger Datentyp erzielt werden kann. Genau deshalb ist
> das eben compiler- bzw. plattformspezifisch und keinesfalls unabhängig.

Ihr redet da von unterschiedlichen Aspekten. Auf welche eingebauten 
Datentypen die typedefs wie uint32_t gemappt sind, ist 
plattformabhängig. Wie groß sie sind, ist es aber natürlich nicht. Das 
ist ja gerade der Sinn dahinter.

von Oliver S. (oliverso)


Lesenswert?

W.S. schrieb:
> Also nochmal: die Datentypen bei C sind schwammig definiert (z.B. keine
> fest definerten Längen)

Der Standard definiert die „schwammig“, aber eine Implementierung 
definiert die dann natürlich vollständig.

> und die Präzisierung mit Attributen (long oder
> short, signed oder unsigned etc.) ist den typischen C-Programmierern zu
> lästig hinzuschreiben,

Das ist natürlich Unsinn.

> Das hatte nun ein Gremium aufgegriffen und gesagt: "wir wollen alle eben
> diese Datentypen umbenennen und dabei uniformierte Bezeichner wählen, so
> daß bei der Verwendung durch den Programmierer auf allen Maschinen ein
> zum vom Programmierer gewünschten Zweck der jeweils passende eigentliche
> Datentyp je nach Compiler verwendet werden soll.

Den Satz verstehst du doch selber nicht mehr…

Die in stdint.h definierten Typen sind Datentypen mit eindeutiger Größe, 
die man direkt erkennen kann.

Oliver

von W.S. (Gast)


Lesenswert?

Oliver S. schrieb:
> Den Satz verstehst du doch selber nicht mehr…

Naja, ich schon, du anscheinend nicht.

Deshalb sag ich es nochmal ein bissel unfreundlicher:

Anstatt endlich einmal die Größen von int und long int in C hinzukriegen 
und damit den jeweiligen Compiler zu modernisieren, hat man sich zu 
nichts besserem als einer Headerdatei entschließen können. Die soll nun 
für mehr Compilerunabhängigkeit sorgen, indem sie die von Programmierer 
zu gebrauchenden Bezeichnungen (wie uint8_t) auf die vom Compiler 
verstandenen Bezeichnungen (wie unsigned char) umsetzt.

Ganz kurz: Keine Modernisierung, sondern wieder mal nur ein popliger 
workaround.

Nur schade, daß die nicht Bezeichner wie 'ottokar' genommen haben. X-)
Das wäre wenigstens lustig.

W.S.

von Noch ein Kommentar (Gast)


Lesenswert?

> Ganz kurz: Keine Modernisierung

Genau das ist das zentrale Feature an C.

Du kannst immer noch 50 Jahre alte Libraries in dein neues Programm 
einbinden. Jede Verbesserung muss zu den prähistorischen K&R 
Konstruktionen kompatibel sein.

Die meisten Leute wollen es genau so haben. Sonst wäre C schon längst in 
der Versenkung verschwunden. Eine der modernen Śprachen hätte sich 
durchgesetzt.


Übrigens: Mit C++ operator overloading kannst du dir uint128_t selbst 
basteln. Aber die Frage, ob das eine gute Idee ist, löst garantiert 
einen Religionskrieg aus.

von Oliver S. (oliverso)


Lesenswert?

Noch ein Kommentar schrieb:
> Übrigens: Mit C++ operator overloading kannst du dir uint128_t selbst
> basteln. Aber die Frage, ob das eine gute Idee ist, löst garantiert
> einen Religionskrieg aus.

Wenn man es braucht, muß man das machen. Wobei, müssen muß man nicht, 
man kann auch einfach eine der verfügbaren „bigint“ libs benutzen, und 
damit noch viel größere Integertypen nutzen. Auch unter C.

Oliver

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.