Is the following code legal?

K

Kiuhnm

#include <new>

class T
{
};

int main()
{
T t = t;
T u(u);
T v;
new (&v) T(v);
}

Kiuhnm
 
B

Ben Pope

Kiuhnm said:
#include <new>

class T
{
};

int main()
{
T t = t;
T u(u);
T v;
new (&v) T(v);
}

Kiuhnm

Have you tried compiling this?

Does you compiler give you errors?

Why do you think that is?

What do you expect each line to do?

Ben Pope
 
K

Kiuhnm

Ben Pope ha scritto:
Have you tried compiling this?

Yes, but it is irrelevant. How can I be sure that my compiler is
completely standard-compliant?
What do you expect each line to do?

It is irrelevant.
All I would like to know is whether the code, according to the standard,
produces a defined behavior or not.

Kiuhnm
 
R

Rolf Magnus

Kiuhnm said:
Ben Pope ha scritto:

Yes, but it is irrelevant. How can I be sure that my compiler is
completely standard-compliant?

You can't.
It is irrelevant.
All I would like to know is whether the code, according to the standard,
produces a defined behavior or not.

Not.
 
D

Daniel T.

Kiuhnm said:
Ben Pope ha scritto:

Yes, but it is irrelevant. How can I be sure that my compiler is
completely standard-compliant?


It is irrelevant.
All I would like to know is whether the code, according to the standard,
produces a defined behavior or not.

T t = t;
T u(u);

The above two lines will compile but the behavior is undefined.


T v;
new (&v) T(v);

The above two lines produce defined behavior.

Please, why do you ask?
 
D

Dietmar Kuehl

Kiuhnm said:
#include <new>

class T
{
};

int main()
{
T t = t;
T u(u);
T v;
new (&v) T(v);
}

What is your particular question anyway? What do you suspect to be
illegal and why? The obvious violation is double construction of an
object which is illegal. However, you put other stuff into the
article, too, which might indicate that you are actually looking for
other sources of "illegal code".
 
A

AnalogFile

Dietmar said:
What is your particular question anyway?

He is asking because we have been discussing that in our national C++
newsgroup but did not come to a definitive conclusion.

There are more variations on the same theme and they may or may not
change the validity of those constructs.
What do you suspect to be
illegal and why?

It depends who you ask to. If we had any consensus we would not even ask.

For as much as we can say the placement new construct is perfectly defined.

That is:

void foo()
{
class T {} v;
new (&v) T(v);
}

is perfectly legal.
The obvious violation is double construction of an
object which is illegal.

Not. The standard does not say you cannot construct twice. And does not
guarantee that the number of constructions matches the number of
destructions. If you reuse the memory of a live object, that object
lifetime ends without the construction being called and it is explicitly
legal to do so. See 3.8#4
However, you put other stuff into the
article, too, which might indicate that you are actually looking for
other sources of "illegal code".

In fact 3.8 is no help in the other cases.

We know that

struct T {
void *p;
T(){}
T(T*pp){ p=pp; if (pp==this) cout << "wow!\n"; }
};

void foo()
{
T t=&t;
T u(&u);
}

is perfectly defined (see 3.3.1#1 and 3.8#5)

But the wording in 3.8, specifically the first item of the list in
3.8#5, together with 3.8#1 seem to imply that

struct T {
int i;
T(){}
T(const T&r){i=r.i;}
};

void foo()
{
T t=t;
T u(u);
}

is undefined behavior (cannot access r.i until the lifetime has begun,
and that happens at the end of the constructor).

And this is apparently incongruous with the fact that

void foo()
{
int i=i;
int j(j);
}

is perfectly valid as in 3.3.1#1
 
K

Kiuhnm

Victor Bazarov ha scritto:
What's the difference from

T t = t;

do you see here?

T may not be a built-in type.

Anyway, my question was subtler than you think:
excerpt from c++ iso/iec 14882:3.3.1 Point of declaration

The /point of declaration/ for a name is immediately after its complete
declarator (clause 8) and before its /initializer/ (if any), except as
noted below.
[Example:

int x = 12;
{ int x = x; }

Here the second x is initialized with its own (indeterminate) value.]
<<<

Then "int x = x;" is /not/ undefined (e.g. a standard-compliant compiler
cannot format your hard disk).

Kiuhnm
 
A

Alf P. Steinbach

* Kiuhnm:
Then "int x = x;" is /not/ undefined (e.g. a standard-compliant compiler
cannot format your hard disk).

Using an indeterminate value, for anything, is formally UB.
 
R

Rolf Magnus

Kiuhnm said:
Victor Bazarov ha scritto:
What's the difference from

T t = t;

do you see here?

T may not be a built-in type.

Anyway, my question was subtler than you think:
excerpt from c++ iso/iec 14882:3.3.1 Point of declaration

The /point of declaration/ for a name is immediately after its complete
declarator (clause 8) and before its /initializer/ (if any), except as
noted below.
[Example:

int x = 12;
{ int x = x; }

Here the second x is initialized with its own (indeterminate) value.]
<<<

Then "int x = x;" is /not/ undefined (e.g. a standard-compliant compiler
cannot format your hard disk).

It doesn't say that. It just says that, when the right hand side is
evaluated, the name 'x' already exists. It doesn't say anything about the
behavior of initializing x with an indeterminate value.
 
K

Kiuhnm

Rolf Magnus ha scritto:
It doesn't say that. It just says that, when the right hand side is
evaluated, the name 'x' already exists. It doesn't say anything about the
behavior of initializing x with an indeterminate value.

3.3.1#1:
"[...]Here the second x is initialized with its own (indeterminate) value."

Kiuhnm
 
K

Kiuhnm

Alf P. Steinbach ha scritto:
* Kiuhnm:



Using an indeterminate value, for anything, is formally UB.

I am just copying it (we cannot overload operator= for built-in types).

Kiuhnm
 
K

Kai-Uwe Bux

Alf said:
* Kiuhnm:

Using an indeterminate value, for anything, is formally UB.

I did a search for "indeterminate" in my electronic version of the standard,
and I did not find a statement to that extend. I would be grateful for
chapter and verse.

It appears that almost all uses (and most definitely all interesting uses)
of indeterminate values lead to undefined behavior per the catch all clause
in [1.3.12]: "Undefined behavior may also be expected when this
International Standard omits the description of any explicit definition of
behavior." However, one could argue that in the case of

int x = x;

the standard actually provides an explicit definition of behavior, namely
that the variable x is initialized in such a way that its value after
initialization is undefined.


Best

Kai-Uwe Bux
 
R

Rolf Magnus

Kiuhnm said:
Rolf Magnus ha scritto:
It doesn't say that. It just says that, when the right hand side is
evaluated, the name 'x' already exists. It doesn't say anything about the
behavior of initializing x with an indeterminate value.

3.3.1#1:
"[...]Here the second x is initialized with its own (indeterminate)
value."

And again, it doesn't say that initializing it with an indeterminate value
is legal, just that it is done here, because x is known before it is
initializied, so the name can be used for the initializer.
 
A

AnalogFile

Alf said:
* Kiuhnm:

Using an indeterminate value, for anything, is formally UB.

Can you point me to where in the standard it says so?

AFAIK it is defined behavior (with indeterminate result) for every POD
type except when dereferencing a pointer.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,763
Messages
2,569,562
Members
45,038
Latest member
OrderProperKetocapsules

Latest Threads

Top