question regarding pointer/reference to temporaries

W

wizwx

Is there anything wrong with the following code?
class A { ... };
class B : public A { ... }; // definitions of class A and B, these are
OK

Foo() {
A & a = B(); // ??
A * p = &B(); // ??
.......
}

I guess a and p are referencing temporaries returned by B(). Is this
the case? Anything wrong?
 
R

red floyd

wizwx said:
Is there anything wrong with the following code?
class A { ... };
class B : public A { ... }; // definitions of class A and B, these are
OK

Foo() {
A & a = B(); // ??
A * p = &B(); // ??
.......
}

I guess a and p are referencing temporaries returned by B(). Is this
the case? Anything wrong?

Make a const, and there's not problem with it. I don't believe it's
valid as written, but can't find chapter&verse to back me up.

I'm not sure if the language allows the second one, but again, I think
it's bad.

Comeau complains about both. Noting that the first case you need an
lvalue on the right. The second, "expression must be an lvalue or
function designator". Since B() is an rvalue, that would do it.
 
A

Andrey Tarasevich

wizwx said:
Is there anything wrong with the following code?
class A { ... };
class B : public A { ... }; // definitions of class A and B, these are
OK

Foo() {

Ill-formed: missing return type. Implicit return types are not allowed in C++.
A & a = B(); // ??

Ill-formed: a non-constant reference cannot be bound to a temporary object.
A * p = &B(); // ??

Ill-formed (assuming that the built-in unary '&' is used): address-of operator
cannot be applied to temporary object since it is not an lvalue.
.......
}

I guess a and p are referencing temporaries returned by B(). Is this
the case? Anything wrong?

The code is ill-formed, which normally means that it cannot be compiled.
 
W

wizwx

Make a const, and there's not problem with it. I don't believe it's
valid as written, but can't find chapter&verse to back me up.

I'm not sure if the language allows the second one, but again, I think
it's bad.

Comeau complains about both. Noting that the first case you need an
lvalue on the right. The second, "expression must be an lvalue or
function designator". Since B() is an rvalue, that would do it.

Thank you for the reply.
First I would like to clarify, that the codes were from an interview,
so no one would really write crappy code like this. But I know there
is something wrong, but I would like to find it out.

I tested the codes in VC6.0. No error message was issued, nor was
there any warning message. But I believe that you are right in that
the reference/pointer should be const, as temporaries cannot be
lvalue.

According to VC6.0,
A & a = B();
'a' would then reference to an (temporary) object. It works just fine
as if 'a' was declared as an object of class B. 'a' is destructed when
the scope closes.

However, for A * b = &B();
the destructor was invoked soon after the line was executed, which
means that 'b' points to a memory while the object no longer exists.

wandering if the lines of codes has compiler-dependent results.
 
W

wizwx

Thank you for the reply.
First I would like to clarify, that the codes were from an interview,
so no one would really write crappy code like this. But I know there
is something wrong, but I would like to find it out.

I tested the codes in VC6.0. No error message was issued, nor was
there any warning message. But I believe that you are right in that
the reference/pointer should be const, as temporaries cannot be
lvalue.

According to VC6.0,
A & a = B();
'a' would then reference to an (temporary) object. It works just fine
as if 'a' was declared as an object of class B. 'a' is destructed when
the scope closes.

However, for A * b = &B();
the destructor was invoked soon after the line was executed, which
means that 'b' points to a memory while the object no longer exists.

wandering if the lines of codes has compiler-dependent results.- Hide quoted text -

- Show quoted text -

Used g++ to test the code. The first was complained, as the reference
should be const. The second got a warning message.
 
A

Andrey Tarasevich

wizwx said:
...
According to VC6.0,
A & a = B();
'a' would then reference to an (temporary) object. It works just fine
as if 'a' was declared as an object of class B. 'a' is destructed when
the scope closes.

However, for A * b = &B();
the destructor was invoked soon after the line was executed, which
means that 'b' points to a memory while the object no longer exists.
...

Both declarations are accepted by VC 6 because of an MS-specific compiler
extension, allowing it to tie pointers and non-constant references to
temporaries. The extensions can be disabled with a /z switch, making VC 6 to
reject this code completely.

From the language point of view, once again, both declarations are ill-formed,
invalid, uncompilable. Any questions about destructors etc. are irrelevant and
make no sense.

If you want to research the MS-specific behavior of VC 6 with extensions, you
need to ask these questions in VC 6 specific newsgroup, since this has nothing
to do with C++ language itself.
 
R

red floyd

wizwx said:
I tested the codes in VC6.0. No error message was issued, nor was
there any warning message. But I believe that you are right in that
the reference/pointer should be const, as temporaries cannot be
lvalue.
VC6 predates the standard and has improper behavior regarding this.
VC7.1 has the incorrect behavior by default "as an extension", but it
can be turned off.
 

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

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top