Hi,

After examining the code further, our inconsistency happened because I did
not give exactly the correct example.  Instead of just struct/class
inside another struct/class, it is struct/class inside a struct inside a
struct/class.

Therefore, in the outer struct/class there is a pointer.  I allocate
memory for this pointer.  When I try to initialize this newly allocated
memory, the gc gets invoked.  So I guess both of us are actually correct:

1) In Data_Make_Struct Ruby fills the resulting struct with zeros.
2) Because Data_Make_Struct (or even Data_Wrap_Struct) may invoke gc, when
we initialize struct members with Data_Make_Struct, we have to do "double
initialization".

Actually the problem is much more general than this.  Before we call any
Ruby function that may invoke gc (such as the innocent looking rb_str_new2
()), we have to make sure that all our data are initialized
properly.  This was tricky because it occured inside my initialization
function itself.  What I mean is, in C usually I do this:

    ptr = (my_type*) malloc (sizeof (my_type));
    ptr->data1 = val;
    ptr->data2 = rb_str_new2 (...);
    ...

Now, in Ruby, I have to change my habit to

    ptr = (type*) malloc (sizeof (type));
    /* Fill in with some generic, default values */
    ptr->data1 = 0;
    ptr->data2 = Qfalse;
    ...
    /* Fill in with the actual data */
    ptr->data1 = val;
    ptr->data2 = rb_str_new2 (...); /* may invoke gc */
    ...

Well, I guess so far the codes that I have dealt with are not as
convoluted as the gc concept.  On the other hand, this supports my
assertion that ALLOC () is much more dangerous than malloc ().  In ALLOC,
we have to make sure that all data are already proper; in malloc () there
is no possibility of jumping around at that point.  Finally, because
Data_Make_Struct really calls ALLOC, then Data_Make_Struct is
indeed dangerous.

Regards,

Bill
============================================================================
nobu.nokada / softhome.net wrote:
>> ---------------------------------------------------
>> > It sounds strange.  Data_Make_Struct() fills the allocated
>> > structure with 0 and rb_gc_mark() ignores 0 which is equal to
>> > Qfalse.
>> ---------------------------------------------------
>> I think this can only happen when we have a struct/class inside
>> another struct/class.  What I observed is, while we are creating the
>> inner struct/class, gc gets called and try to mark the outer
>> struct/class.  Are you saying that even in this case it is safe
>> because the outer struct/class should all be filled with zeros?

> Yes, I guess so.

>> Based on your response above, are you saying that this
>> "double-initializing" is actually not needed?  (in which case, the
>> error is actually generated somewhere else?)

> It should be in Data_Make_Struct().