Date: Wed, 21 Aug 2019 20:29:42 -0500
On Wed, Aug 21, 2019 at 6:38 PM sdkrystian via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> > It's nothing to do with the value of the int object as a whole, but of
> the leftmost byte. Why on earth would it *not* depend on endianness?
>
> Because the standard says so. Here are some citations:
>
> In that particular cast, the value of the pointer is unchanged.
> http://eel.is/c++draft/expr.static.cast#13.sentence-4
>
> Since the value is unchanged, it still points to the int object.
> Therefore, when the indirection operator is used, it yields an lvalue of
> type `char` that denotes the object the pointer points to.
> http://eel.is/c++draft/expr.unary.op#1.sentence-1
>
This part is fine.
>
> Now, when an lvalue-to-rvalue conversion is applied to the lvalue (such as
> during initialization), the result is the value of the object (which has
> NOT been truncated), and since that value is within the representable range
> of `char`, the behavior is well defined, and will ALWAYS yield 42.
>
This part does not follow.
>
> (If it's outside the representable range of char, the behavior is
> undefined http://eel.is/c++draft/expr.pre#4)
>
On a 32-bit little endian system, the value 42 is represented in memory as
[42, 0, 0, 0].
On a 32-bit big endian system, the value 42 is represented in memory as [0,
0, 0, 42].
The char* that you're getting is pointing to the first char, which can have
either value. As the text you're citing states, the value of the char* must
be the value of the int* - so it must point to the first byte in memory.
Which byte is in that slot depends on the endianness of the system.
In order for the char* dereference to give you 42 on a big endian system,
the cast we do would've had to move the pointer value. But the pointer
value must remain unchanged.
Barry
std-proposals_at_[hidden]> wrote:
> > It's nothing to do with the value of the int object as a whole, but of
> the leftmost byte. Why on earth would it *not* depend on endianness?
>
> Because the standard says so. Here are some citations:
>
> In that particular cast, the value of the pointer is unchanged.
> http://eel.is/c++draft/expr.static.cast#13.sentence-4
>
> Since the value is unchanged, it still points to the int object.
> Therefore, when the indirection operator is used, it yields an lvalue of
> type `char` that denotes the object the pointer points to.
> http://eel.is/c++draft/expr.unary.op#1.sentence-1
>
This part is fine.
>
> Now, when an lvalue-to-rvalue conversion is applied to the lvalue (such as
> during initialization), the result is the value of the object (which has
> NOT been truncated), and since that value is within the representable range
> of `char`, the behavior is well defined, and will ALWAYS yield 42.
>
This part does not follow.
>
> (If it's outside the representable range of char, the behavior is
> undefined http://eel.is/c++draft/expr.pre#4)
>
On a 32-bit little endian system, the value 42 is represented in memory as
[42, 0, 0, 0].
On a 32-bit big endian system, the value 42 is represented in memory as [0,
0, 0, 42].
The char* that you're getting is pointing to the first char, which can have
either value. As the text you're citing states, the value of the char* must
be the value of the int* - so it must point to the first byte in memory.
Which byte is in that slot depends on the endianness of the system.
In order for the char* dereference to give you 42 on a big endian system,
the cast we do would've had to move the pointer value. But the pointer
value must remain unchanged.
Barry
Received on 2019-08-21 20:31:55