C++ Logo

sg12

Advanced search

Re: [ub] type punning through congruent base class?

From: Gabriel Dos Reis <gdr_at_[hidden]>
Date: Sat, 18 Jan 2014 10:00:56 +0000
| -----Original Message-----
| From: ub-bounces_at_[hidden] [mailto:ub-bounces_at_[hidden]] On
| Behalf Of David Krauss
| Sent: Friday, January 17, 2014 9:06 PM
| To: WG21 UB study group
| Subject: Re: [ub] type punning through congruent base class?
|
|
| On Jan 18, 2014, at 12:13 PM, Gabriel Dos Reis <gdr_at_[hidden]> wrote:
|
| > | But how do you know what object is unconstructed?
| >
| > I do not understand the question; could you clarify?
| >
| > | An unconstructed object
| > | pops into existence when you perform an access, and that's enough to
| validate
| > | my awful example. This is what I meant by "retroactive."
| >
| > I don't understand. We define what it means for a raw memory to be
| constructed as an object.
|
| You proposed that an access causes the memory to be treated from that point
| as an unconstructed POD object, just as access in a constructor. But that rule
| is already loose enough to render the idea of a lifetime essentially without
| effect.

The last sentence is your assertion. I am saying I do not understand it. Could you detail the reasoning?
 
| The only criterion for having an accessible but not-yet-constructed POD
| object is trying to use it (as an overlay to memory that doesn't already contain
| a non-trivially destructible object).

Why?

| Whatever you try to use, you have. That's just the worst interpretation of the status quo.

Again, I do not understand.

| > | Inside a constructor, the type of *this is well-defined, and the exception is
| > | granted over a limited scope. Outside a constructor, it's a free for all.
| >
| > I don't understand this. I am saying that if you get dynamically allocated
| storage of proper alignment and size, then the first write access is, by
| definition, construction of an object of type given by the lvalue used to
| perform the write.
|
| And then you can arbitrarily say that any point in the code is a user-defined
| dynamic allocator which enables a new lifetime to begin by reusing the
| storage.

I do not understand this.

| The comments in my earlier example emphasized this.
|
| Perhaps what we need is a way to stop lifetimes from ending by reuse.

Why? It is already an acquired concept.

| Then requiring delete-expressions would be useful.

We do not require that for non-POD object, why should that be required here?

| > | I don't know about rules in C,
| >
| > the relevant rules have been extensively referenced in this thread. There
| were a couple of messages specifically dedicated to that last night.
|
| I know that if you try to alias structures in C, layout differences can bite you,
| but I don't see what prevents you from doing so as long as layouts are the
| same (which can be checked using member-wise offsetof). "Congruence" is
| there in the title of this thread.

"congruent" is in the title but it is defined anywhere in C++ for classes. So, unless you are more precise about what you are saying, it is hard to understand.
Just having the same layout isn't sufficient to say "Oh, it is OK, go ahead and do whatever you want". On a defined platform, an IEEE-conformant double and a 64-bit long may have the same alignment and size; we aren't saying it is OK to alias them.
 
| I haven't seen anything like "effective type" for C structs or C++ POD class
| types.

Because I do not see the point of introducing 'effective type' when we have 'dynamic type'.
The whole point of saying that the object is constructed is to assert that its 'dynamic type' is now known (which corresponds to 'effective type' in C).
See my previous message(s) on this point.

| Aliasing rules only apply at lvalue-to-rvalue conversion of fundamental
| types.
|
| So given the earlier discussion, I still don't know what rules in C prevent you
| from punning congruent classes.

We are trying to define a missing case for C++ - not C.

-- Gaby

Received on 2014-01-18 11:01:27