Go Back   ZeroC Forums > Bug Reports

Reply
 
LinkBack Thread Tools Rate Thread Display Modes
  #1 (permalink)  
Old 07-12-2007
mspycher mspycher is offline
Registered User
 
Name: Matthias Spycher
Organization: Arteris
Project: Evaluation
 
Join Date: May 2007
Posts: 7
Post slice2cpp: member initialization in default constructor

Using Ice 3.2.0 on Linux RH3 and GCC 3.3.5, I've run into a problem related to the lack of member initialization in default constructors generated by the slice2cpp compiler. Attached is the test program; search for TODO to see what makes the test case succeed. Without explicit member initialization, the program throws the exception in AImpl::dispose() and valgrind says the following:

... Conditional jump or move depends on uninitialised value(s)
...

I'm not sure if this is a GCC compiler issue or not, but explicitly initializing the primitive member 'A::mFlags' solves the problem for me.

I have not tried to reproduce the problem with another compiler.
Attached Files
File Type: zip InitTest.zip (726 Bytes, 8 views)
Reply With Quote
  #2 (permalink)  
Old 07-12-2007
mspycher mspycher is offline
Registered User
 
Name: Matthias Spycher
Organization: Arteris
Project: Evaluation
 
Join Date: May 2007
Posts: 7
Not a bug, just a request for enhancement

On closer examination it is obvious why the exception is thrown. The same memory region is being used for both objects and so the flag will be set unless the member is initialized to 0. I apologize for filing this as a bug.

It might be useful to have an option in slice2cpp that would initialize all members, including those of built-in types, in the default constructor of a class. I have an example where I must pass many arguments to a class constructor, only one of which is really required to initialize a member of type
Code:
::Ice::Long
. In this case I would prefer to have a class where the default constructor produces an object where the initial values of all members are well-defined. I also understand this is not how C++ is defined to work.

Matthias
Reply With Quote
  #3 (permalink)  
Old 07-12-2007
michi's Avatar
michi michi is offline
ZeroC Staff
 
Name: Michi Henning
Organization: ZeroC
Project: Ice
 
Join Date: Feb 2003
Location: Brisbane, Australia
Posts: 909
The problem with generating code that initializes such data members is that it incurs a performance penalty. Moreover, built-in types such as long are never initialized by C++ and doing so just for Slice types would be inconsistent with how C++ works.

The performance penalty is potentially serious once you think about sequences of built-in types, or sequences of structs or classes containing built-in types. In that case, we'd end up initializing a lot of data that, most likely, would end up having the wrong value anyway.

So, I think it unlikely that we'd add such initialization.

Note that, for Slice classes, you can easily arrange for default initialization yourself (even for non-abstract classes). Simply register an object factory by calling Communicator::addObjectFactory. Now Ice, whenever it needs to create your class will call your object factory to instantiate the class. You can have the object factory either return a C++ class that is derived from the Slice-generated class, or (if the class is non-abstract), have the factory initialize the data members of the Slice-generated class before it returns the instance to the Ice run time.

Section 6.14.5 in the manual gives you the run-down on this.

Cheers,

Michi.
Reply With Quote
  #4 (permalink)  
Old 07-13-2007
mspycher mspycher is offline
Registered User
 
Name: Matthias Spycher
Organization: Arteris
Project: Evaluation
 
Join Date: May 2007
Posts: 7
Using factories to initialize members selectively

Thanks for the response and advice, I'm basically doing what you suggest. The performance argument is a good one too, especially for aggregate members. Nonetheless, if an option were available in slice to annotate classes so their primitive members would be initialized by the default constructor (e.g. as they are in Java), I would use it.

On a related note, I noticed that the generated constructor taking arguments to initialize all members has an initializer list which repeats the initialization of all inherited state at every level in the inhertiance hierarchy. Is this to guarantee a certain order of initialization?

Matthias
Reply With Quote
  #5 (permalink)  
Old 07-13-2007
beagles's Avatar
beagles beagles is offline
ZeroC Staff
 
Name: Brent Eagles
Organization: ZeroC, Inc
Project: Ice Developer
 
Join Date: Feb 2003
Location: Newfoundland
Posts: 110
Quote:
... I noticed that the generated constructor taking arguments to initialize all members has an initializer list which repeats the initialization of all inherited state at every level in the inhertiance hierarchy. Is this to guarantee a certain order of initialization?
In C++, every virtual base class is constructed by the most derived class. The initialization lists in the constructors for each generated class need to include calls to the constructors for each virtual base class in order for the base classes to be properly constructed.

Brent
Reply With Quote
  #6 (permalink)  
Old 07-13-2007
michi's Avatar
michi michi is offline
ZeroC Staff
 
Name: Michi Henning
Organization: ZeroC
Project: Ice
 
Join Date: Feb 2003
Location: Brisbane, Australia
Posts: 909
Quote:
Originally Posted by mspycher View Post
Nonetheless, if an option were available in slice to annotate classes so their primitive members would be initialized by the default constructor (e.g. as they are in Java), I would use it.
One acid test for adding a feature to Ice is the question "Can the developer reasonably achieve what they want without the feature?" If so, the feature is unlikely to be added because it would amount to a convenience function.

Of course, Ice does contain a number of convenience functions. But, when it does, they are for things that most developers want to do often (as opposed to things that a few developers want to do rarely). In other words, if demand for a convenience feature is big, that sometimes warrants adding the feature.

The fundamental design tradeoff here is whether the added complexity for everyone is worth the added convenience for some developers.

One of the appealing things of Ice is that it is simple and easy to learn and that, almost always, developers don't pay for what they don't use. Every feature we add makes APIs bigger and requires extra documentation. The documentation issue is serious because, usually, the extra feature means that the developer has to wade through more text about a topic to find what he or she needs, which adds extra friction. (Even if a feature is invisible at the API level (or Slice level) until it is needed, it becomes visible in the documentation.)

You might want to read my recent article on API Design for more thoughts on the matter.

Quote:
On a related note, I noticed that the generated constructor taking arguments to initialize all members has an initializer list which repeats the initialization of all inherited state at every level in the inhertiance hierarchy.
As Brent already pointed out, Slice classes support multiple inheritance which means we must use virtual C++ inheritance. But C++ requires all bases of a virtually derived class to be instantiated by the constructor of the most-derived class.

Cheers,

Michi.
Reply With Quote
  #7 (permalink)  
Old 07-13-2007
mspycher mspycher is offline
Registered User
 
Name: Matthias Spycher
Organization: Arteris
Project: Evaluation
 
Join Date: May 2007
Posts: 7
Thanks

Brent and Michi

I appreciate the detailed response and understand where you're coming from regarding extensions to ICE/slice. No problem.

Thank you also for clarifying the initialization of virtual bases.

Cheers and have a good weekend.
Matthias
Reply With Quote
  #8 (permalink)  
Old 07-16-2007
michi's Avatar
michi michi is offline
ZeroC Staff
 
Name: Michi Henning
Organization: ZeroC
Project: Ice
 
Join Date: Feb 2003
Location: Brisbane, Australia
Posts: 909
Quote:
Originally Posted by michi View Post
As Brent already pointed out, Slice classes support multiple inheritance which means we must use virtual C++ inheritance. But C++ requires all bases of a virtually derived class to be instantiated by the constructor of the most-derived class.
Actually, I need to correct myself here. The main motivation for doing this is that to not do so would mean that you could have a partially-initialized class. The way it is, you are forced to initialize all members of the class, including the members of base classes, which makes partical initialization impossible.

The reason Ice generates virtual inheritance for bases is so that you can use Slice class in multiple implementation inheritance without ending up with multiple copies of a base.

Cheers,

Michi.
Reply With Quote
Reply



Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Similar Threads
Thread Thread Starter Forum Replies Last Post
Call to a member function GetID() on a non-object rama Help Center 0 12-15-2006 10:12 AM
member ambiguity error when creating a smart pointer heathbar Help Center 3 04-09-2006 06:32 PM
derived constructor generation bug in slice2cpp bpolivka Bug Reports 3 03-02-2006 10:42 AM
Identity Constructor acbell Comments 1 08-30-2005 02:34 PM
Constructor and Default-Parameter Mr.Freeze Help Center 1 08-13-2003 08:07 AM


All times are GMT -4. The time now is 07:47 PM.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.0.0
(c) 2008 ZeroC, Inc.