Reputation: 151
In this answer and the attached comments, Pavel Minaev makes the following argument that, in C, the only types to which uint8_t
can be typedef'd are char
and unsigned char
. I'm looking at this draft of the C standard.
uint8_t
implies the presence of a corresponding type int8_t
(7.18.1p1).int8_t
is 8 bits wide and has no padding bits (7.18.1.1p1).uint8_t
is also 8 bits wide.unsigned char
is CHAR_BIT
bits wide (5.2.4.2.1p2 and 6.2.6.1p3).CHAR_BIT
is at least 8 (5.2.4.2.1p1).CHAR_BIT
is at most 8, because either uint8_t
is unsigned char
, or it's a non-unsigned char
, non-bit-field type whose width is a multiple of CHAR_BIT
(6.2.6.1p4).Based on this argument, I agree that, if uint8_t
exists, then both it and unsigned char
have identical representations: 8 value bits and 0 padding bits. That doesn't seem to force them to be the same type (e.g., 6.2.5p14).
Is it allowed that uint8_t
is typedef'd to an extended unsigned integer type (6.2.5p6) with the same representation as unsigned char
? Certainly it must be typedef'd (7.18.1.1p2), and it cannot be any standard unsigned integer type other than unsigned char
(or char
if it happens to be unsigned). This hypothetical extended type would not be a character type (6.2.5p15) and thus would not qualify for aliased access to an object of an incompatible type (6.5p7), which strikes me as the reason a compiler writer would want to do such a thing.
Upvotes: 15
Views: 1923
Reputation: 283921
uint8_t
may exist and be a distinct type from unsigned char
.
One significant implication of this is in overload resolution; it is platform-dependent whether:
uint8_t by = 0;
std::cout << by;
uses
operator<<(ostream, char)
operator<<(ostream, unsigned char)
oroperator<<(ostream, int)
Upvotes: 0
Reputation: 25723
int8_t and uint8_t differ only by REPRESENTATION and NOT the content(bits). int8_t uses lower 7 bits for data and the 8th bit is to represent "sign"(positive or negative). Hence the range of int8_t is from -128 to +127 (0 is considered a positive value).
uint8_t is also 8 bits wide, BUT the data contained in it is ALWAYS positive. Hence the range of uint8_t is from 0 to 255.
Considering this fact, char is 8 bits wide. unsigned char would also be 8 bits wide but without the "sign". Similarly short and unsigned short are both 16 bits wide.
IF however, "unsigned int
" be 8 bits wide, then .. since C isn't too type-nazi, it IS allowed. And why would a compiler writer allow such a thing? READABILITY!
Upvotes: -1
Reputation: 183978
In 6.3.1.1 (1) (of the N1570 draft of the C11 standard), we can read
The rank of any standard integer type shall be greater than the rank of any extended integer type with the same width.
So the standard explicitly allows the presence of extended integer types of the same width as a standard integer type.
There is nothing in the standard prohibiting a
typedef implementation_defined_extended_8_bit-unsigned_integer_type uint8_t;
if that extended integer type matches the specifications for uint8_t
(no padding bits, width of 8 bits), as far as I can see.
So yes, if the implementation provides such an extended integer type, uint8_t
may be typedef'ed to that.
Upvotes: 4
Reputation: 215617
If uint8_t
exists, the no-padding requirement implies that CHAR_BIT
is 8. However, there's no fundamental reason I can find why uint8_t
could not be defined with an extended integer type. Moreover there is no guarantee that the representations are the same; for example, the bits could be interpreted in the opposite order.
While this seems silly and gratuitously unusual for uint8_t
, it could make a lot of sense for int8_t
. If a machine natively uses ones complement or sign/magnitude, then signed char
is not suitable for int8_t
. However, it could use an extended signed integer type that emulates twos complement to provide int8_t
.
Upvotes: 5