Reputation: 536
I'm trying to assign a value to the member of an union which is member of a struct, but the value doesn't seem to be assigned.
I've stepped through the program, and right after the assignation, len_param.data
value seems to be some sort of pointer (see GDB output at the end of the post)
Also, if I printf
, it runs normally:
len_param.data.v_int = 4;
// If I uncomment this line, IT RUNS FINE! WHY?
// printf("len_param.data.v_int: %i \n", len_param.data.v_int);
The type of len_param
is as follow:
struct Parameter {
enum {
NORMAL, ARRAY, SKIP,
} type;
GIDirection direction;
GIArgument data;
};
And GIArgument
definition:
union _GIArgument
{
gboolean v_boolean;
gint8 v_int8;
guint8 v_uint8;
gint16 v_int16;
guint16 v_uint16;
gint32 v_int32;
guint32 v_uint32;
gint64 v_int64;
guint64 v_uint64;
gfloat v_float;
gdouble v_double;
gshort v_short;
gushort v_ushort;
gint v_int;
guint v_uint;
glong v_long;
gulong v_ulong;
gssize v_ssize;
gsize v_size;
gchar * v_string;
gpointer v_pointer;
};
typedef _GIArgument GIArgument;
The complete file can be found here: https://gist.github.com/romgrk/642388914a9ff412eb5683fca44009d7#file-function-cc-L255
And my GDB output when I step at that line is:
Thread 1 "node" hit Breakpoint 1, GNodeJS::FunctionInvoker (info=...) at ../src/function.cc:256
256 len_param.data.v_int = GetV8ArrayLength(info[in_arg]);
(gdb) step
GNodeJS::GetV8ArrayLength (value=...) at ../src/function.cc:25
25 static int GetV8ArrayLength (Local<Value> value) {
(gdb) finish
Run till exit from #0 GNodeJS::GetV8ArrayLength (value=...) at ../src/function.cc:25
GNodeJS::FunctionInvoker (info=...) at ../src/function.cc:260
260 callable_arg_values[length_i].v_pointer = &len_param.data;
Value returned is $1 = 4
(gdb) p len_param.data.v_int
$2 = -17928
(gdb) p len_param
$3 = {
type = GNodeJS::Parameter::SKIP,
direction = GI_DIRECTION_INOUT,
data = {
v_boolean = -17928,
v_int8 = -8 '\370',
v_uint8 = 248 '\370',
v_int16 = -17928,
v_uint16 = 47608,
v_int32 = -17928,
v_uint32 = 4294949368,
v_int64 = 140737488337400,
v_uint64 = 140737488337400,
v_float = -nan(0x7fb9f8),
v_double = 6.9533558069492434e-310,
v_short = -17928,
v_ushort = 47608,
v_int = -17928,
v_uint = 4294949368,
v_long = 140737488337400,
v_ulong = 140737488337400,
v_ssize = 140737488337400,
v_size = 140737488337400,
v_string = 0x7fffffffb9f8 "\t\357\304\303J\a",
v_pointer = 0x7fffffffb9f8
}
}
Upvotes: 1
Views: 188
Reputation: 340218
The problem might be that nothing is ever done with len_param.data
except to take its address just before it goes out of scope and the lifetime of len_param
expires. So the compiler figures there's no point storing anything there.
Here's the code snippet where len_param
is defined, used and dies (with unnecessary code elided and some annotation comments added):
if (param.type == Parameter::ARRAY) {
// ...
Parameter len_param = call_parameters[length_i]; // len_param is defined
if (len_param.direction == GI_DIRECTION_IN) {
// ...
}
else if (len_param.direction == GI_DIRECTION_INOUT) {
len_param.data.v_int = GetV8ArrayLength(info[in_arg]);
callable_arg_values[length_i].v_pointer = &len_param.data;
}
} // len_param goes out of scope, so it's no longer alive
// and the pointer that got placed in `callable_arg_values[length_i].v_pointer`
// is pointing to garbage
The root problem is that the pointer in callable_arg_values[length_i].v_pointer
isn't valid moments after it gets stored.
Upvotes: 1