www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Problem with "delete" and what about "friend" classes & functions?

reply John Kiro <johnkirollos yahoo.com> writes:
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
Jan 05 2007
next sibling parent Kirk McDonald <kirklin.mcdonald gmail.com> writes:
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
Jan 05 2007
prev sibling next sibling parent Sean Kelly <sean f4.ca> writes:
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
Jan 05 2007
prev sibling next sibling parent reply Johan Granberg <lijat.meREM OVE.gmail.com> writes:
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.
Jan 05 2007
parent John Kiro <johnkirollos yahoo.com> writes:
== 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"

if I read the error mesage correctly the compiler thinks you want

 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?


 pros and cons. Something to notice thou is that in D everything in

 module has full access to all fields, as sort of implicit friend

 everything in the module.

Yes.. putting the 2 friends in the same module looks like a good alternative for me. Thanks friends John
Jan 06 2007
prev sibling parent %u <u digitaldaemon.com> writes:
== 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.
Jan 05 2007