class c{
int i_;
public:
c(int i){
printf("c\r\n"); i_ = i;
}
~c(){
printf("~c\r\n"); i_ = -1;
}
void foo() const{
printf("foo,%d", i_);
}
};
class a{
public:
const c & c_;
a() : c_( c(1) )
{
}
};

int main()
{
a _1;
_1.c_.foo();
}

The ~c() will never invoke.
So RAII is a dream.

Re: VC BUG,SO BIG by Alexander

Alexander
Tue Sep 19 22:06:46 CDT 2006

Note that c(1) temporary should be destroyed when the constructor ends
(12.2.5: A temporary bound to a reference member in a
constructor's ctorinitializer (12.6.2) persists until the constructor
exits). Calling foo() on it brings undefined result.

The bug is that ~c() is not called, But it's very marginal case (not BIG
BUG), because such constructs are unusable: why do you care of a referene
bound to a destroyed temporary object.

"Darwin" <codecopier@gmail.com> wrote in message
news:1158719630.018012.219550@i3g2000cwc.googlegroups.com...
> class c{
> int i_;
> public:
> c(int i){
> printf("c\r\n"); i_ = i;
> }
> ~c(){
> printf("~c\r\n"); i_ = -1;
> }
> void foo() const{
> printf("foo,%d", i_);
> }
> };
> class a{
> public:
> const c & c_;
> a() : c_( c(1) )
> {
> }
> };
>
> int main()
> {
> a _1;
> _1.c_.foo();
> }
>
> The ~c() will never invoke.
> So RAII is a dream.
>



Re: VC BUG,SO BIG by Igor

Igor
Tue Sep 19 22:12:04 CDT 2006

"Darwin" <codecopier@gmail.com> wrote in message
news:1158719630.018012.219550@i3g2000cwc.googlegroups.com
> class c{
> int i_;
> public:
> c(int i){
> printf("c\r\n"); i_ = i;
> }
> ~c(){
> printf("~c\r\n"); i_ = -1;
> }
> void foo() const{
> printf("foo,%d", i_);
> }
> };
> class a{
> public:
> const c & c_;
> a() : c_( c(1) )
> {
> }
> };
>
> int main()
> {
> a _1;
> _1.c_.foo();
> }
>
> The ~c() will never invoke.
> So RAII is a dream.

It should be noted that your program exhibits undefined behavior. It
binds c_ reference to a temporary that is destroyed at the end of a's
constructor. You then call a method on a dangling reference. From C++
standard:

12.2/5 ... A temporary bound to a reference member in a constructor's
ctor-initializer (12.6.2) persists until the constructor exits...

Nevertheless, the destructor should have run, and it does not appear to,
so that definitely looks like a bug. I don't believe it's as dramatic as
you make it to be - your example is rather contrived and unlikely to
occur in practice (why would anybody want to have dangling reference as
a member?). Anyway, you can submit the bug here:

http://connect.microsoft.com/feedback/default.aspx?SiteID=210

If and when you do, post a reference to the bug here so others can
validate it.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925



Re: VC BUG,SO BIG by Stuart

Stuart
Wed Sep 20 03:05:07 CDT 2006

Darwin wrote:

> class c{
> int i_;
> public:
> c(int i){
> printf("c\r\n"); i_ = i;
> }
> ~c(){
> printf("~c\r\n"); i_ = -1;
> }
> void foo() const{
> printf("foo,%d", i_);
> }
> };
> class a{
> public:
> const c & c_;
> a() : c_( c(1) )
> {
> }
> };
>
> int main()
> {
> a _1;
> _1.c_.foo();
> }
>
> The ~c() will never invoke.
> So RAII is a dream.
>

This code doesn't even compile under VC6.0!

Stuart

Re: VC BUG,SO BIG by Alex

Alex
Wed Sep 20 05:41:47 CDT 2006

"Igor Tandetnik" wrote:
> It should be noted that your program exhibits undefined
> behavior. It binds c_ reference to a temporary that is
> destroyed at the end of a's constructor. You then call a
> method on a dangling reference. From C++ standard:
>
> 12.2/5 ... A temporary bound to a reference member in a
> constructor's ctor-initializer (12.6.2) persists until the
> constructor exits...

"Alexander Grigoriev" wrote:
> Note that c(1) temporary should be destroyed when the
> constructor ends (12.2.5: A temporary bound to a reference
> member in a
> constructor's ctorinitializer (12.6.2) persists until the
> constructor exits). Calling foo() on it brings undefined
> result.

Igor, Alexander,

Do you have any plausible explanation why such exception was
made for constructor-initializer list? As I see it this
shouldn't be too difficult for compiler to hold temporary
object for lifetime of reference member. Something like
that:

struct X
{
const Y& m_y;
X() : m_y(Y(42)) {}
};

// in pseudocode:

struct X
{
const Y& m_y;
bool __m_y_istemp;


X::X()
{
m_y = someY;
__m_y_istemp = __istemp(someY);
}

X::~X()
{
if(__m_y_istemp)
m_y.~Y();
}
};

The disadvantages of above sample are:

1. Additional boolean member per member reference.

2. Non-trivial destructor. However, if Y's destructor is
trivial, then compiler could optimize away both
`X::__m_y_istemp' and `X::~X()', so no impact would be made
on X at all.

Thanks in advance
Alex



Re: VC BUG,SO BIG by Alex

Alex
Wed Sep 20 06:32:53 CDT 2006

"Alex Blekhman" wrote:
> [...]
> The disadvantages of above sample are:
>
> 1. Additional boolean member per member reference.
>
> 2. Non-trivial destructor. However, if Y's destructor is
> trivial, then compiler could optimize away both
> `X::__m_y_istemp' and `X::~X()', so no impact would be
> made on X at all.


While thinking little bit more about it I realized that
compiler will need to allocate some storage in order
temporary object to stay alive for lifetime of enclosing
object. Compiler cannot store temporary on stack, because it
will be destroyed upon exit from constructor (as it happens
today). So, the possible solutions are

1. Make hidden storage room at least as large as
sizeof(T) for each member reference of type T. Then store
there temporary object if required. This is clearly insane
and contradicts the whole purpose of reference.

2. Store temporary objects somewhere else in global
space. It will be difficult to implement, since number and
size of possible temporaries are unknown in advance.

I reckon that's why no attempt was made to store temporaries
longer than constructor's scope.

Any thoughts are appreciated
Alex



Re: VC BUG,SO BIG by Bertrand

Bertrand
Thu Sep 21 10:24:05 CDT 2006

> This code doesn't even compile under VC6.0!

Like lots of valid C++ code. What's your point?

Re: VC BUG,SO BIG by peter

peter
Fri Sep 22 05:44:02 CDT 2006


Bertrand Augereau wrote:
> > This code doesn't even compile under VC6.0!
>
> Like lots of valid C++ code. What's your point?

But this code is not valid. I do not believe that a diagnostic is
required.

/Peter


Re: VC BUG,SO BIG by Bertrand

Bertrand
Fri Sep 22 05:56:08 CDT 2006

>>> This code doesn't even compile under VC6.0!
>> Like lots of valid C++ code. What's your point?
>
> But this code is not valid. I do not believe that a diagnostic is
> required.

Of course, but not compiling on VC6.0 doesn't give much information,
does it?

Comeau doesn't issue any warning either, by the way.