The documentation is correct. And these macros exist for different purposes, which is why they are defined differently. `JL_GC_PUSHARGS` allocates gc-rooted space and stores a reference to it in the first argument. `JL_GC_PUSH` does not allocate space, it instead takes the address(es) of existing variables and uses them as slots for the garbage collector's reachability analysis.
On Fri, Mar 27, 2015 at 4:12 PM Philip Roth <[email protected]> wrote: > > I'm embedding calls to Julia code within other languages, and have noticed > what I think is an inconsistency in the implementation of the JL_GC_PUSH* > macros. With the JL_GC_PUSH1, JL_GC_PUSH2, etc. macros, the documentation > on embedding shows to pass the *address* of the jl_value_t pointer > variable to the macro, e.g.: > > jl_value_t* jret = NULL; > JL_GC_PUSH1( &jret ); > > However, if using JL_GC_PUSHARGS, the documentation says to just store the > jl_value_t pointer value itself, e.g.: > > jl_value_t* jret = NULL; > jl_value_t** gcargs; > JL_GC_PUSHARGS(gcargs, 1); > gcargs[0] = jret; > > I've verified using a debugger that the JL_GC_PUSH1 case stores the > address of the pointer variable in the GC stack frame, whereas > JL_GC_PUSHARGS stores the pointer variable's value itself. > > I tried changing my use of JL_GC_PUSHARGS so that it will accept the > address of the jl_value_t pointer variable (made gcargs a jl_value_t*** and > set gcargs[0] to &jret), but the implementation assumes that gcargs is a > jl_value_t** and so it won't compile. Conversely, I tried passing just > jret to the JL_GC_PUSH1 macro. It compiles, but the program SEGVs if I > force a garbage collection after pushing the value. Based on this, I think > the JL_GC_PUSHARGS macro implementation is incorrect. > > So: is this operator error? Or a bug in the implementation/documentation? > > >
