Date: Wed, 21 Aug 2019 18:49:20 -0500
On Wed, Aug 21, 2019, at 6:38 PM, sdkrystian via Std-Proposals 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
That is static_cast. The topic is reinterpret_cast.
>
> 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
>
> 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.
>
> (If it's outside the representable range of char, the behavior is undefined http://eel.is/c++draft/expr.pre#4)
I wonder if this should be promoted to implementation defined, of even fully defined. I think everybody knows what will happen in practice anyway. I've even been known to rely on the result (truncation) in some cases. Though unlike reinterpret_cast I don't know that it matters as this is probably a case of don't do that.
For reinterpret_cast I want as many cases as possible implementation defined. I often need to rely on it to work as it actually does in practice.
> -------- Original message --------
> From: Jake Arkinstall via Std-Proposals <std-proposals_at_[hidden]>
> Date: 8/21/19 19:24 (GMT-05:00)
> To: std-proposals_at_[hidden]
> Cc: Jake Arkinstall <jake.arkinstall_at_[hidden]>
> Subject: Re: [std-proposals] Allowing access to object representations
>
> 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?
>
> On Wed, Aug 21, 2019 at 11:49 PM sdkrystian via Std-Proposals <std-proposals_at_[hidden]> wrote:
>> > On big-endian systems we'll end up with `ch==0`; on little-endian systems we'll have `ch==42`.
>>
>> I think not - the value of the int object does not truncate. It's value is 42.
>>
>> -------- Original message --------
>> From: Arthur O'Dwyer via Std-Proposals <std-proposals_at_[hidden]>
>> Date: 8/21/19 17:30 (GMT-05:00)
>> To: std-proposals_at_[hidden]
>> Cc: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
>> Subject: Re: [std-proposals] Allowing access to object representations
>>
>> On Wed, Aug 21, 2019 at 4:37 PM language.lawyer--- via Std-Proposals <std-proposals_at_[hidden]> wrote:
>>> On 21/08/2019 22:51, language.lawyer_at_[hidden] wrote:
>>> > On 21/08/2019 22:44, Timur Doumler via Std-Proposals wrote:
>>> >> So you're saying that, even without any pointer arithmetic, just this code:
>>> >>
>>> >> int x = 100000;
>>> >> std::cout << *reinterpret_cast<char*>(&x);
>>> >>
>>> >> has undefined behaviour?
>>> >>
>>> >> If that's the case then this is even more insane than I thought. Please clarify whether this is really what you're saying here!
>>> >
>>> > I suspect you was trying to answer my mail, but anyways yes, I think that your example has UB.
>>>
>>> UB if 100000 is outside of the range representable by char, ofc.
>>> On a platform where char represents the same range of values as int the code obviously won't have UB.
>>
>> Well, regardless of your views on UB, we can all agree that the behavior of
>> int x = 42;
>> char ch = *reinterpret_cast<char*>(&x);
>> is not portable. On big-endian systems we'll end up with `ch==0`; on little-endian systems we'll have `ch==42`. (This contradicts something sdkrystian said earlier; he seemed to be under the impression that `ch==42` always.)
>>
>> Whether the integer value of `x` happens to be less than CHAR_MAX doesn't matter at all; the behavior is implementation-defined at best — and UB at worst. I'm inclined to believe the people who say it's UB, because in my experience pretty much anything involving `reinterpret_cast` is UB.
>>
>> However, all is not lost — it'll still do what you expect, in practice! :)
>>
>> –Arthur
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
> > 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
That is static_cast. The topic is reinterpret_cast.
>
> 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
>
> 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.
>
> (If it's outside the representable range of char, the behavior is undefined http://eel.is/c++draft/expr.pre#4)
I wonder if this should be promoted to implementation defined, of even fully defined. I think everybody knows what will happen in practice anyway. I've even been known to rely on the result (truncation) in some cases. Though unlike reinterpret_cast I don't know that it matters as this is probably a case of don't do that.
For reinterpret_cast I want as many cases as possible implementation defined. I often need to rely on it to work as it actually does in practice.
> -------- Original message --------
> From: Jake Arkinstall via Std-Proposals <std-proposals_at_[hidden]>
> Date: 8/21/19 19:24 (GMT-05:00)
> To: std-proposals_at_[hidden]
> Cc: Jake Arkinstall <jake.arkinstall_at_[hidden]>
> Subject: Re: [std-proposals] Allowing access to object representations
>
> 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?
>
> On Wed, Aug 21, 2019 at 11:49 PM sdkrystian via Std-Proposals <std-proposals_at_[hidden]> wrote:
>> > On big-endian systems we'll end up with `ch==0`; on little-endian systems we'll have `ch==42`.
>>
>> I think not - the value of the int object does not truncate. It's value is 42.
>>
>> -------- Original message --------
>> From: Arthur O'Dwyer via Std-Proposals <std-proposals_at_[hidden]>
>> Date: 8/21/19 17:30 (GMT-05:00)
>> To: std-proposals_at_[hidden]
>> Cc: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
>> Subject: Re: [std-proposals] Allowing access to object representations
>>
>> On Wed, Aug 21, 2019 at 4:37 PM language.lawyer--- via Std-Proposals <std-proposals_at_[hidden]> wrote:
>>> On 21/08/2019 22:51, language.lawyer_at_[hidden] wrote:
>>> > On 21/08/2019 22:44, Timur Doumler via Std-Proposals wrote:
>>> >> So you're saying that, even without any pointer arithmetic, just this code:
>>> >>
>>> >> int x = 100000;
>>> >> std::cout << *reinterpret_cast<char*>(&x);
>>> >>
>>> >> has undefined behaviour?
>>> >>
>>> >> If that's the case then this is even more insane than I thought. Please clarify whether this is really what you're saying here!
>>> >
>>> > I suspect you was trying to answer my mail, but anyways yes, I think that your example has UB.
>>>
>>> UB if 100000 is outside of the range representable by char, ofc.
>>> On a platform where char represents the same range of values as int the code obviously won't have UB.
>>
>> Well, regardless of your views on UB, we can all agree that the behavior of
>> int x = 42;
>> char ch = *reinterpret_cast<char*>(&x);
>> is not portable. On big-endian systems we'll end up with `ch==0`; on little-endian systems we'll have `ch==42`. (This contradicts something sdkrystian said earlier; he seemed to be under the impression that `ch==42` always.)
>>
>> Whether the integer value of `x` happens to be less than CHAR_MAX doesn't matter at all; the behavior is implementation-defined at best — and UB at worst. I'm inclined to believe the people who say it's UB, because in my experience pretty much anything involving `reinterpret_cast` is UB.
>>
>> However, all is not lost — it'll still do what you expect, in practice! :)
>>
>> –Arthur
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
Received on 2019-08-21 18:52:01