Thread overview
Problem with "delete" and what about "friend" classes & functions?
Jan 05, 2007
John Kiro
Jan 05, 2007
Kirk McDonald
Jan 05, 2007
Sean Kelly
Jan 05, 2007
Johan Granberg
Jan 06, 2007
John Kiro
Jan 06, 2007
%u
January 05, 2007
Hello

I have a problem with this statement:

  delete pDoc.getFile();

It generates this error:

"Error: ((cast(CDoc)(pDoc)).getFile)() is not an lvalue"

The getFile() is a member of CDoc (pDoc is an object of a CDoc
derived class), and is defined like this:

  CFile getFile()
  {
	return m_pFile;
  }

So any idea about the reason of this error?
The code compiles successfully if I replace the delete statement with:

  CFile tmpFile=pDoc.getFile();
  delete tmpFile;

Another point, I guess D doesn't support "friend" classes or functions.. wouldn't they be useful sometimes?

Thanks
John
January 05, 2007
John Kiro wrote:
> Hello
> 
> I have a problem with this statement:
> 
>   delete pDoc.getFile();
> 
> It generates this error:
> 
> "Error: ((cast(CDoc)(pDoc)).getFile)() is not an lvalue"
> 
> The getFile() is a member of CDoc (pDoc is an object of a CDoc
> derived class), and is defined like this:
> 
>   CFile getFile()
>   {
> 	return m_pFile;
>   }
> 
> So any idea about the reason of this error?
> The code compiles successfully if I replace the delete statement with:
> 
>   CFile tmpFile=pDoc.getFile();
>   delete tmpFile;
> 

'delete' also sets the reference to null. Therefore, it must operate on an lvalue.

> Another point, I guess D doesn't support "friend" classes or
> functions.. wouldn't they be useful sometimes?
> 

Everything in the same module is a 'friend'.

-- 
Kirk McDonald
Pyd: Wrapping Python with D
http://pyd.dsource.org
January 05, 2007
John Kiro wrote:
> Hello
> 
> I have a problem with this statement:
> 
>   delete pDoc.getFile();
> 
> It generates this error:
> 
> "Error: ((cast(CDoc)(pDoc)).getFile)() is not an lvalue"
> 
> The getFile() is a member of CDoc (pDoc is an object of a CDoc
> derived class), and is defined like this:
> 
>   CFile getFile()
>   {
> 	return m_pFile;
>   }
> 
> So any idea about the reason of this error?

Pretend that delete is actually a function declared like this:

    void delete( inout void* val )
    {
        free( val );
        val = null;
    }

rvalues (ie. temporaries) cannot be passed to functions by reference because they don't have a concrete address (basically).  So you first have to store the result in an lvalue (a normal variable) before calling delete on it.

> The code compiles successfully if I replace the delete statement with:
> 
>   CFile tmpFile=pDoc.getFile();
>   delete tmpFile;
> 
> Another point, I guess D doesn't support "friend" classes or
> functions.. wouldn't they be useful sometimes?

They are.  But "friend" as a keyword isn't necessary in D because of the way visibility specifiers work.  "private" actually means "visible to everything in the current module" and "package" means "visible to everything in the current package."  And "protected" means "visible to everything in the current module (I think) and to derived classes."  So in essence, you can think of all class members as automatically being friends with one another.


Sean
January 05, 2007
John Kiro wrote:

> Hello
> 
> I have a problem with this statement:
> 
>   delete pDoc.getFile();
> 
> It generates this error:
> 
> "Error: ((cast(CDoc)(pDoc)).getFile)() is not an lvalue"

have you tried this "delete (pDoc.getFile());" ?
if I read the error mesage correctly the compiler thinks you want do delete
a function. (I have no compiler nearby so I cant test it)

> Another point, I guess D doesn't support "friend" classes or functions.. wouldn't they be useful sometimes?

Probably but I think they can cause trouble too, it comes down to weighting pros and cons. Something to notice thou is that in D everything in the same module has full access to all fields, as sort of implicit friend with everything in the module.
January 06, 2007
== Auszug aus John Kiro (johnkirollos@yahoo.com)'s Artikel
> So any idea about the reason of this error?

You protected a pointer variable in a class with a getter.
Now you want to delete the object rooted in that pointer variable
from outside the class containing the pointer variable, thereby
leaving the value stored in that pointer variable unmodified.

This means you want that pointer variable in the class to have an invalid address---to point to an object which does not exist anymore.

The D compiler allows you to shoot in your foot if you really really want to.
January 06, 2007
== Quote from Johan Granberg (lijat.meREM@OVE.gmail.com)'s article
> John Kiro wrote:
> > Hello
> >
> > I have a problem with this statement:
> >
> >   delete pDoc.getFile();
> >
> > It generates this error:
> >
> > "Error: ((cast(CDoc)(pDoc)).getFile)() is not an lvalue"
> have you tried this "delete (pDoc.getFile());" ?
> if I read the error mesage correctly the compiler thinks you want
do delete
> a function. (I have no compiler nearby so I cant test it)


It's rather the reason mentionned by Kirk & Sean: Attempting to use
the return of a function as a left-value.
So it seems that in this case the pointer invalidation done by
"delete" has lost its meaning, due to the workaround (defining a tmp
reference), because it will invalidate the tmp reference, not the
actual one (m_pFile).. but this is not be a big deal.. "delete" in
C++ doesn't touch the pointer anyway.


> > Another point, I guess D doesn't support "friend" classes or functions.. wouldn't they be useful sometimes?
> Probably but I think they can cause trouble too, it comes down to
weighting
> pros and cons. Something to notice thou is that in D everything in
the same
> module has full access to all fields, as sort of implicit friend
with
> everything in the module.


Yes.. putting the 2 friends in the same module looks like a good alternative for me.

Thanks friends
John