From: "José Augusto" Date: 2003-04-05T00:00:21+09:00 Subject: Re: Strange behavior in C-declared global variable? Hi Thanks, i'ts really the 'global' versus 'local' problem (rookie error ;-)... In fact it is the 'global' scope of the memory where 'temp' is what counts. By declaring 'static VALUE temp;' or 'VALUE temp;' as global, outside of the function, the problem disapears. I examined carefully the code in the Ruby's variable.c file. There are the following functions: 'rb_global_entry' is the function that creates -- i.e., ** allocs ** -- the global memory for a new global variable; 'rb_define_variable' --> gets a global_id ID value and calls 'rb_global_entry'; 'rb_gv_set' --> calls 'rb_global_entry' and 'rb_gvar_set' to set the variable. The function 'rb_global_entry' is the key for creating global vars. It sees if the variable already exists: if it exists it returns a pointer to it; if not, allocates memory for a new variable (structures global_variable and global_entry) and returns a pointer to global_entry. The problem with my code, as Kent Dahl and Guy Decous in another answer pointed out, was that I was using &temp, ** a pointer to a local value, ** in the function 'rb_define_variable("$tempor",&temp)'. Of course temp vanishes after exiting the function. However, 'rb_gv_set("$tempor",temp)' ** uses really temp **, not a pointer to it, and with it there is no problem, as Guy Decoux pointed out very well in other reply. So the following code, with temp a local variable, works as I intended: ........... static VALUE newvar(int argc, VALUE *argv, VALUE self) { VALUE temp; // ***** local var temp = rb_ary_new(); rb_ary_push(temp, rb_float_new(3.3)); rb_gv_set("$tempor", temp); // ***** uses temp, not &temp ............ In fact there is a solution to the problem without using temp at all :-) static VALUE newvar(int argc, VALUE *argv, VALUE self) { rb_ary_push(rb_gv_set("$tempor", rb_ary_new()), rb_float_new(3.3)); ............ which uses only ** global memory ** returned by rb_ary_push, rb_gv_set, etc... The key for this is that 'rb_gv_set("$varname",VALUE val )' returns VALUE val, which allows to reuse VALUE val in 'rb_ary_push'. Thanks again J. Augusto Kent Dahl wrote: > Jos� Augusto wrote: > > ------------------------------------------------ > > > > require 'inline' # use Inline module > > > > class Fake > > > > inline_c_raw %q[ > > > > static VALUE newvar(int argc, VALUE *argv, VALUE self) { > > VALUE temp; > > > > temp = rb_ary_new(); > > rb_ary_push(temp, rb_float_new(3.3)); > > rb_define_variable("$tempor", &temp); > > rb_global_variable(&temp); > ^ > This should have set of your alarm bells. Notice that you give in a > pointer to the VALUE (i.e. the container), which has local scope and is > gone after your C function returns. > > Declaring temp as: > > static VALUE temp; > > might help, but my C/C++ is rusty. > > HTH > > -- > (\[ Kent Dahl ]/)_ _~_ __[ http://www.stud.ntnu.no/~kentda/ ]___/~ > ))\_student_/(( \__d L b__/ NTNU - graduate engineering - 5. year ) > ( \__\_�|�_/__/ ) _)Industrial economics and technological management( > \____/_�_\____/ (____engineering.discipline_=_Computer::Technology___)