| ▲ | eesmith 11 hours ago | ||||||||||||||||
The linked-to essay points out that char is only "at least 8 bits", and links to https://cppreference.com/c/language/arithmetic_types which confirms that point. https://smd.hu/Data/Analog/DSP/SHARC/C&C++%20Compiler%20&%20... says the cc21k compiler for ADSP-21xxx DSP systems has char as 32 bits signed, and that the compiler handles ANSI/ISO standard C. So I don't believe your statement "sizeof(char) is guaranteed to always be 1" is correct. > chars are also how you access the byte-level representation of objects in C Where does the spec say that a char can be used to address any point in an object? There's all sorts of oddities like tagged architectures which the C spec handles which I know essentially nothing about, but which break common expectations about how C works. I believe this is one of them. I believe the following is undefined behavior in C, even though your compiler may let you do it, at least sometimes, and on modern desktop hardware:
I believe the following is the correct (or less incorrect) way to do it: | |||||||||||||||||
| ▲ | aw1621107 9 hours ago | parent [-] | ||||||||||||||||
> The linked-to essay points out that char is only "at least 8 bits", and links to https://cppreference.com/c/language/arithmetic_types which confirms that point. Yes, but in C standardese a "byte" is not necessarily the 8 bits that it's normally thought to be these days. From C89 Section 2.2.4.2 Numerical Limits [-1]: > maximum number of bits for smallest object that is not a bit-field (byte) CHAR_BIT 8 i.e., CHAR_BIT is the number of bits in a byte. C23 has a similar definition, and further defines CHAR_WIDTH that is defined to expand to the same value as CHAR_BIT. > So I don't believe your statement "sizeof(char) is guaranteed to always be 1" is correct. From C89 section 3.3.3.4 The sizeof operator [0]: > When applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1. This wording remains basically identical through C23 [1]. > Where does the spec say that a char* can be used to address any point in an object? From C89 section 3.3 Expressions: > An object shall have its stored value accessed only by an lvalue that has one of the following types: > <snip> > * a character type. This also remains the case up through C23. I think you're thinking of the strict aliasing rule with your example, but character types are one of the exceptions to said rule so I think your example is actually fully defined. It'd be UB if you casted to an incompatible type like a float, I believe. [-1]: https://port70.net/%7Ensz/c/c89/c89-draft.html#2.2.4.2 [0]: https://port70.net/%7Ensz/c/c89/c89-draft.html#3.3.3.4 [1]: https://port70.net/%7Ensz/c/c23/n3220.html#6.5.4.4 | |||||||||||||||||
| |||||||||||||||||