Hi,

To give it more context, suppose struct_B contains a VALUE (a pure VALUE,
which is not a wrapper):

    typedef struct
    {
        VALUE data4;
    } struct_B;

and the marking function for the top level wrapper object is as follows:

    ....
    if (ptr->data1) rb_gc_mark (ptr->data1...);
    if (ptr->data2) rb_gc_mark (ptr->data2->data4);
    ....

Therefore, when "ptr->data1 = ALLOC (struct_A);" is executed, ptr->data2
may not be NULL.

I also like your suggestion of SAFE_ALLOC(), although for philosophical
reason, I choose SAFE_MALLOC().

Regards,

Bill
==================================================================
Mauricio Fern?ndez <batsman.geo / yahoo.com> wrote:
>> which is involved in some rb_gc_mark() because struct_C is part of
>> (but not direct) internal data of some class.  

> If I understand it correctly, you've got a pointer to a struct_C value
> inside the struct that is actually Data_Wrap_Struct()'ed.

> It seems to me that either
>  * the struct_C value is ALLOCated or malloc()ed and there's no need
>    to mark any VALUE whatsoever (as it isn't wrapped), so it won't attempt
>    to mark data1 and data2 before these parts of the struct are properly
>    initialized
>  * you use Data_Make_Struct and the struct is memset to 0, so nothing
>   bad happens if the mark function is called by rb_gc_mark(). 

>> Now, the following code
>> may fail:
>> 
>>     ....
>>     ptr = ALLOC (struct_C);
>>     ptr->data1 = ALLOC (struct_A);    /* may fail here because of
>> rb_gc() */
>>     ptr->data2 = ALLOC (struct_B);

> Why? There's no marking involved if you only use ALLOC, AFAIK.
> No way ptr->data1 and ptr->data2 can be used before initialized.

> I can't see the point of this, but wouldn't SAFE_ALLOC (a wrapper to
> ALLOC which memsets to 0) be a better solution?


> I don't really see the problem in the code above; maybe if you gave a
> little more context. I think it's a non-issue as no marking function is
> involved to mark the fields of struct_C, AFAIK.