Huh? How do you think `const char *s = "Hello"; const char *t = &s[1];` works?
> Why should pointer size determine value size though?
Because you should be able to take the address of any value, and addresses have byte granularity.
That's debatable, though. One could argue that languages should explicitly support "values that are never going to have their address taken, be passed by reference/pointer, etc." which would only become addressable, e.g. as part of a struct.
I think you and the parent are using different definitions of granularity. The parent meant that sizeof(t) could be 32 or 64 bits. I think you just meant that the smallest thing the pointer references is the address of a single byte.
Rust already has fat pointers though. A reference to a smaller byte value could be a pointer plus a bit-mask.
So this is just an example of a pointer offset by 1 slot. It's not conceptually all that different to take sub-values of a slot.
To work with values that consume fractions of a byte, such as a 3-bit integer, a pointer + a bit offset is used to grab that value (that complexity is abstracted by the compiler). My argument is the bit shift necessary to load the 3-bits you need from the 8-bit slot is one of the cheapest operations a CPU can do. Meanwhile using 3-bits when all you need is 3-bits allows for things like arrays and packed structs to use much less memory than padding everything to 8 bits.
And why shouldn't a language support that?
If some pointers have a bit offset but others don't, OK, I guess, but I'd argue that at that point it'd be a cleaner design to just have a "pointer plus bit offset" be a separate type from "regular pointer". And that would get back to the problem that you would have a type that you couldn't take a "regular" pointer to.