Hacker News

Favorites Setup
Comment by aw1621107 | original | C for Rust programmers
[−]aw1621107 · 2026-10-10 Sat 22:01 UTC · link
> 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

[2]: https://port70.net/%7Ensz/c/c89/c89-draft.html#3.3

[3]: https://port70.net/%7Ensz/c/c23/n3220.html#6.5.1

[−]eesmith · 2026-10-11 Sun 03:51 UTC · link
I .... okay, my mind is blown. It absolutely says that, and https://en.cppreference.com/cpp/language/types adds "this allows the extreme case in which bytes are sized 64 bits, all types (including char) are 64 bits wide, and sizeof returns 1 for every type."

So that scaling factor is placed into CHAR_BIT, and would be 64 on that DSP compiler.

> An object shall have its stored value accessed only by an lvalue that has one of the following types:

Yes, my confusion comes down to my confusion of what "byte" means in the C spec.

Thank you for your time in pointing this out.

[−]aw1621107 · 2026-10-11 Sun 05:35 UTC · link
Yeah, it's one of those things that is not exactly intuitive if you didn't already know about it. The menagerie of other byte-ish-sized types added in recent versions of C and C++ probably doesn't help either.

Bit of a (not so?) fun fact: char* being a universal alias can lead to some potentially unexpected slowdowns [0], especially if the char* bit is behind a typedef.

[0]: https://travisdowns.github.io/blog/2019/08/26/vector-inc.htm...