C++ Logo

SG12

Advanced search

Subject: Re: [ub] type punning through congruent base class?
From: Kazutoshi Satoda (k_satoda_at_[hidden])
Date: 2014-01-16 21:57:23


On 2014/01/17 5:53 +0900, Gabriel Dos Reis wrote:
> | struct B { int x };
> | struct B* p = (B*) malloc(sizeof(B));
> | p->x = 17;
> |
> | This (modulo the cast) has been how C has handled dynamic allocation
> | of structs approximately forever. There are no constructors in C,
> | structs don't get initialized, their fields just get assigned to.
>
> Could you walk us through the C standards and explain what you believe this program fragment is supposed to do and what actually is at the address pointed by p?
> I think that will be a very illuminating exercise -- and would possibly help clear some confusions.

Let me try the exercise. I'm referring WG14 N1570.
http://www.open-std.org/jtc1/sc22/wg14/www/standards.html

p points an object (a region of data storage, 3.15) which is allocated
by malloc(). The object has allocated storage duration (6.2.4) and its
lifetime starts at the allocation in malloc(), and ends at deallocation
in free() (7.22.3).

"p->x" yields an lvalue of type int which designates an object at
address pointed by ((char*)p + offsetof(B, x)). There is no rule about
the effective type of the object pointed by p to evaluate the "->"
expression. (6.5.2.3)

"p->x = 17" makes the effective type of the object between &p->x and
(&p->x + 1) becomes int (6.5 p6), and stores value 17 (a value
representation of int which represents 17) into that object (6.5.16).

(Note)
In C, there is no such a thing like "an object of type int" unlike in
C++ where an object has a type and the type is determined when the
object is created. In C, "object" is a merely a region of data storage,
and may be labeled by an effective type which is determined by ongoing
or previous access to the object at a time.

If "struct B x = *p" follows the above code, the access (lvalue
conversion, 6.3.2.1 p2) on *p, which is allowed by the aliasing rule
(6.5 p7, bullet 5 "an aggregate or union ..."), changes the effective
type of the object at p.

I hope this is correct and does help.

-- 
k_satoda

SG12 list run by herb.sutter at gmail.com