5 ms·
One point about char is that a pointer to a character type (character types are char, unsigned char, signed char - see 6.2.5.15) may alias non-char objects in a
by to3m 11y ago
One point about char is that a pointer to a character type (character types are char, unsigned char, signed char - see 6.2.5.15) may alias non-char objects in a standard-compliant fashion (see 6.3.2.3.7). But uint8_t and int8_t may not necessarily be suitable replacements, because they are defined to be integer types (see B.19 - character types are a subset of integer types), and in any event may not even exist (7.20.1.1.3).
- xcgvgh 11y agoI think the whole article needs a preface, assuming CHAR_BIT is defined as 8.
- messe 11y agoThat still doesn't mean that `uint8_t` will be defined as `char`.
- xcgvgh 11y agoWith my assumption, it will be defined as an unsigned char, as it should be.
- to3m 11y agoBut it doesn't have to be - the 8-bit integer types could map to 8-bit implementation-defined integer types instead. Such types would not necessarily to have the same aliasing behaviour as their equivalently sized and equivalently signed character types.
- xcgvgh 11y agoTypedef doesn't create a new type, it merely creates a new name for a type. I don't know what you mean by implementation defined integer type. If the implementation is conforming, then any integer type that isn't a basic C integer type, is really just a typedef for one of the basic C integer types ( char, short int, int, long, ... ). In C, with CHAR_BIT defined as 8, unsigned char is the only type that satisfies the requirements of uint8_t. ( It is also possible that it is defined as char, if implementation defines char to have the same range, representation, and behavior as unsigned char. In this case, char effectively becomes unsigned char, but is still a distinct type. The types are compatible (can alias).) Now why is unsigned char the only possibility. Type uint8_t is defined to have two'2 complement, have exactly 8 bits, no padding, and be unsigned. So we need an unsigned integer type. The unsigned type that follows unsigned char in rank is unsigned short char. But this type is defined to have ranges at least from 0 to 65535. Since CHAR_BIT is 8, unsigned short int cannot be used, because it has to have more than 8 bits. As there is no type in rank before unsigned char, it remains the only possibility.
- julian-klode 11y agoYou could have types __builtin_type_like_char_that_is_not_char and __builtin_type_like_uchar_that_is_not_uchar
- xcgvgh 11y agoThere are no such things in the C Standard.
- to3m 11y agoThe standard provides for implementation-defined integer types. See my other comment: https://news.ycombinator.com/item?id=10868435 https://news.ycombinator.com/item?id=10868435 See also this suggestion that the gcc people, true to form, considered making uint8_t something other than unsigned char: https://news.ycombinator.com/item?id=10868953 https://news.ycombinator.com/item?id=10868953
- xcgvgh 11y agoI apologize. I wasn't aware of extended integer types.
- noselasd 11y agoNo. C allows the implementation(A C compiler) to create an internal integer type that is none of the standard integer types and alias that to (u)intX_t , using an implementation defined mechanism other than typedef. Or it could use a typedef .e.g typedef __special_u8 uint8_t; where the particular compiler internally knows about __special_u8 and treats it differently from unsigned char.
- to3m 11y agoI found a web version of the draft standard, so here are some links: 6.2.5.15 - http://port70.net/~nsz/c/c11/n1570.html#6.2.5p15 http://port70.net/~nsz/c/c11/n1570.html#6.2.5p15 6.3.2.3.7 - http://port70.net/~nsz/c/c11/n1570.html#6.3.2.3p7 http://port70.net/~nsz/c/c11/n1570.html#6.3.2.3p7 B.19 - actually I think 7.20.1 is a better demonstration that these are integer types (and not, since it's never mentioned, character types) - http://port70.net/~nsz/c/c11/n1570.html#7.20.1 http://port70.net/~nsz/c/c11/n1570.html#7.20.1 7.20.1.1.3 - http://port70.net/~nsz/c/c11/n1570.html#7.20.1.1p3 http://port70.net/~nsz/c/c11/n1570.html#7.20.1.1p3
- joveian 11y agoI think it isn't clear what the standard means here. If uint8_t exists it must be a typedef to unsigned char (edit: unless to3m is right that there could be a distinct 8-bit implementation-defined integer type, which I didn't think was allowed but maybe it is), so the question is if a typedef to a character type is a character type. My reading is that it isn't, but I've heard enough good C programmers assume that it is that either I am wrong or hopefully compilers will always allow uint8_t to work in this case. It certainly makes more sense to use uint8_t than unsigned char for that usage, but ideally maybe there would be a standard byte_alias_t or such.
- to3m 11y agoA typedef to a character type is a character type. See http://port70.net/~nsz/c/c11/n1570.html#6.7.8p3 http://port70.net/~nsz/c/c11/n1570.html#6.7.8p3. http://port70.net/~nsz/c/c11/n1570.html#6.2.5p4 http://port70.net/~nsz/c/c11/n1570.html#6.2.5p4 leaves open the option for extended signed integer types, and the following paragraph provides for an unsigned integer type for each signed type, extended signed types included. So it would be perfectly possible, if not actually very reasonable - not that this is stopping anybody at the moment - for an implementation to provide __int8, a signed 8-bit integer type that fulfils all the requirements of uint8_t, but is not a character type, and use that as uint8_t. Then, conceivably, it could fail to support the use of uint8_t pointers to alias other objects, something supported by the more usual situation of using unsigned char for uint8_t. I'm not sure that anybody would do this, but they could. I'm rather surprised gcc doesn't do it, come to think of it, just to teach its users a lesson. Maybe I should file a bug report?
- joveian 11y agoThanks, good to know the full situation. I'll try to remember not to use uint8_t that way in the future, just in case. I looked briefly previously and somehow got the sense that extended types could only be larger than standard types, but this time I found that 6.3.1.1 explicitly mentions same width extended types. Personally, I've been happy with GCC's decisions on such issues.
- klodolph 11y agoThe GCC developers talked about making uint8_t something other than unsigned char and figured they would probably get lynched if they did that (because uint8_t aliasing rules would be different). While the standard agrees with you, practice is somewhat different.