Date: Thu, 20 Mar 2014 19:05:12 +0800
On 2014–03–20, at 5:25 AM, Jens Maurer <Jens.Maurer_at_[hidden]> wrote:
> On 03/18/2014 06:06 AM, David Krauss wrote:
>> uint32_t datum = * (net_word< uint32_t > *) buf_ptr;
>
> What's "buf_ptr”?
A blob of data with no dynamic type. It’s supposed to be idiomatic, cast-happy C using a memory overlay struct.
> Anyway, you seem to be aliasing a net_word
> with a uint32_t, which seems to be undefined behavior according
> to 3.10p10.
“If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined: … a char or unsigned char type.”
The only value being accessed after the alias is through an lvalue of char type.
The address of the net_word is the same as the address of its first member, so if member access expressions run afoul of 3.10/10 (certainly on-topic for this question; it’s not clear to me that they do), the functions could reinterpret_cast< char * >( this ) and there would be no access to the class object whatsoever.
Merely forming a pointer is not aliasing. You can cast pointers to whatever and back per [expr.reinterpret.cast] 5.2.10/7.
>> Is it any safer to jump through a little hoop with placement new?
>>
>> uint32_t datum = * new( buf_ptr ) net_word< uint32_t >;
>
> This destroys the previous contents of *buf_ptr, from a
> specification point-of-view.
It runs the constructor of a trivially-constructible class, which does nothing and has no particular significance. The object lifetime already began when “storage with the proper alignment and size for type T is obtained,” which occurred when the data blob was allocated.
>> Would any part of this mayhem be vulnerable to future semantic restrictions?
>
> Which part of the future do you wish me to predict?
There’s been quite a bit of discussion on this group about adjusting the aliasing and lifetime rules. The last I recall, new-expressions were being considered to become more significant with respect to object lifetime and dynamic type.
> On 03/18/2014 06:06 AM, David Krauss wrote:
>> uint32_t datum = * (net_word< uint32_t > *) buf_ptr;
>
> What's "buf_ptr”?
A blob of data with no dynamic type. It’s supposed to be idiomatic, cast-happy C using a memory overlay struct.
> Anyway, you seem to be aliasing a net_word
> with a uint32_t, which seems to be undefined behavior according
> to 3.10p10.
“If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined: … a char or unsigned char type.”
The only value being accessed after the alias is through an lvalue of char type.
The address of the net_word is the same as the address of its first member, so if member access expressions run afoul of 3.10/10 (certainly on-topic for this question; it’s not clear to me that they do), the functions could reinterpret_cast< char * >( this ) and there would be no access to the class object whatsoever.
Merely forming a pointer is not aliasing. You can cast pointers to whatever and back per [expr.reinterpret.cast] 5.2.10/7.
>> Is it any safer to jump through a little hoop with placement new?
>>
>> uint32_t datum = * new( buf_ptr ) net_word< uint32_t >;
>
> This destroys the previous contents of *buf_ptr, from a
> specification point-of-view.
It runs the constructor of a trivially-constructible class, which does nothing and has no particular significance. The object lifetime already began when “storage with the proper alignment and size for type T is obtained,” which occurred when the data blob was allocated.
>> Would any part of this mayhem be vulnerable to future semantic restrictions?
>
> Which part of the future do you wish me to predict?
There’s been quite a bit of discussion on this group about adjusting the aliasing and lifetime rules. The last I recall, new-expressions were being considered to become more significant with respect to object lifetime and dynamic type.
Received on 2014-03-20 12:05:22