Meta-Programmierung: char und int8_t
-
Folgendes ist mir beim Rumspielen mit MetaProgrammierung aufgefallen:
char c; std::cout << std::is_same<decltype(c), int8_t>::value << std::endl; std::cout << std::is_same<decltype(c), char>::value << std::endl; int i; std::cout << std::is_same<decltype(i), int>::value << std::endl; std::cout << std::is_same<decltype(i), int32_t>::value << std::endl;
Ergibt: 0111
D.h. ein char ist kein int8_t
aber ein int ist ein int32_tWtf?
Ist das jetzt bei mir nur ein Compilerspezifisches Thema, oder ist das generell so? Ich ging ursprünglich davon aus, dass die int**_t-Typen eigentlich nur Typedefs sind ?
Kann mir hier jemand Nachhilfe geben?
-
@It0101
int8_t
wird einsigned char
sein.
uint8_t
einunsigned char
.
Das sind Ganzzahltypen mit kleinem Wertebereich.char
ist der Typ für Zeichen.
-
@It0101 sagte in Meta-Programmierung: char und int8_t:
Ergibt: 0111
Komisch, bei mir übersetzt das nicht. Fehlt ja auch mindestens ein main ...
-
#include <iostream> #include <cstdint> int main() { signed char c; std::cout << std::is_same<decltype(c), int8_t>::value << std::endl; std::cout << std::is_same<decltype(c), signed char>::value << std::endl; int i; std::cout << std::is_same<decltype(i), int>::value << std::endl; std::cout << std::is_same<decltype(i), int32_t>::value << std::endl; return 0; }
Also "signed char" passt in dem Fall zu int8_t. Aber was ist jetzt der Unterschied zwischen "signed char" und "char". Die zusätzlich Angabe von "signed" ist ja bei INT auch nicht üblich, bzw. generell unüblich. Ich ging eigentlich bisher davon aus, dass "signed char" und "char einunddasselbe sind...
Während "int" und "signed int" offensichtlich Synonyme sind, ist das bei "signed char" und "char nicht der Fall....
-
@It0101 sagte in Meta-Programmierung: char und int8_t:
Während "int" und "signed int" offensichtlich Synonyme sind, ist das bei "signed char" und "char nicht der Fall....
Korrekt. Und char kann auch unsigned sein.
-
@It0101
Interessante Beobachtung. Ich habe mal deinen Code etwas aufgebohrt:#include <iostream> #include <cstdint> int main(int argc, char* argv[]) { std::cout << std::endl << "*** char ***" << std::endl; char c; std::cout << "int8_t:\t\t" << std::is_same<decltype(c), int8_t>::value << std::endl; std::cout << "uint8_t:\t" << std::is_same<decltype(c), uint8_t>::value << std::endl; std::cout << "char:\t\t" << std::is_same<decltype(c), char>::value << std::endl; std::cout << "signed char:\t" << std::is_same<decltype(c), signed char>::value << std::endl; std::cout << "unsigned char:\t" << std::is_same<decltype(c), unsigned char>::value << std::endl; std::cout << std::endl << "*** signed char ***" << std::endl; signed char c1; std::cout << "int8_t:\t\t" << std::is_same<decltype(c1), int8_t>::value << std::endl; std::cout << "uint8_t:\t" << std::is_same<decltype(c1), uint8_t>::value << std::endl; std::cout << "char:\t\t" << std::is_same<decltype(c1), char>::value << std::endl; std::cout << "signed char:\t" << std::is_same<decltype(c1), signed char>::value << std::endl; std::cout << "unsigned char:\t" << std::is_same<decltype(c1), unsigned char>::value << std::endl; std::cout << std::endl << "*** unsigned char ***" << std::endl; unsigned char c2; std::cout << "int8_t:\t\t" << std::is_same<decltype(c2), int8_t>::value << std::endl; std::cout << "uint8_t:\t" << std::is_same<decltype(c2), uint8_t>::value << std::endl; std::cout << "char:\t\t" << std::is_same<decltype(c2), char>::value << std::endl; std::cout << "signed char:\t" << std::is_same<decltype(c2), signed char>::value << std::endl; std::cout << "unsigned char:\t" << std::is_same<decltype(c2), unsigned char>::value << std::endl; return 0; }
Als Ergebnis bekomme ich:
*** char *** int8_t: 0 uint8_t: 0 char: 1 signed char: 0 unsigned char: 0 *** signed char *** int8_t: 1 uint8_t: 0 char: 0 signed char: 1 unsigned char: 0 *** unsigned char *** int8_t: 0 uint8_t: 1 char: 0 signed char: 0 unsigned char: 1
-
@It0101
Habe die Antwort gefunden:
Plain char, signed char, and unsigned char are three distinct types
-
@Quiche-Lorraine Das merkt man auch, wenn man Pointer auf diese Typen nimmt.
cout gibt bei *char einen C-String aus.
-
Danke @Quiche-Lorraine
D.h. für mich als Konsequenz:
Wenn ich in der Meta-Programmierung die Byte-Datentypen abprüfen will, reicht es wenn ich auf "unsigned char, signed char und char" abprüfe und habe damit auch die beiden "uint8_t" und "int8_t" erschlagen.
-
@It0101 Nimm Zeugs aus
<limits>
?
-
@It0101 sagte in Meta-Programmierung: char und int8_t:
Also "signed char" passt in dem Fall zu int8_t. Aber was ist jetzt der Unterschied zwischen "signed char" und "char". Die zusätzlich Angabe von "signed" ist ja bei INT auch nicht üblich, bzw. generell unüblich. Ich ging eigentlich bisher davon aus, dass "signed char" und "char einunddasselbe sind...
Nein, es gibt historisch gewachsen Plattformen auf denen ein
char
unsigned ist (Ubuntu Server auf dem Raspberry Pi ist es), und es gibt Plattformen auf denenchar
signed (Linux auf Intel64) ist. Deshalb gibt es diesen Dreiklang an Typenchar
,unsigned char
undsigned char
. Dazu muss man aufpassen, da man auf Grund der C bzw. C++ Norm nicht voraussetzen darf, dasschar
8Bit hat. Auch das ist historisch gewachsen, und es gab auch Plattformen bei denenchar
mehr als 8Bit hatten. UNIX verlangt mittlerweile explizit, dasschar
8Bit ist.Deshalb ist nicht garantiert, dass man
uint8_t
oderint8_t
synonym fürchar
verwenden kann, bzw. diese Typen überhaupt definiert sind.