【问题标题】:Why can't I assign an int to the union member of a struct member?为什么我不能将 int 分配给结构成员的联合成员?
【发布时间】:2018-06-21 21:33:54
【问题描述】:

我正在尝试为作为结构成员的联合成员分配一个值,但该值似乎没有被分配。 我已经逐步完成了程序,在分配之后,len_param.data 值似乎是某种指针(请参阅帖子末尾的 GDB 输出)

另外,如果我printf,它运行正常:

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);

len_param的类型如下:

struct Parameter {
    enum {
        NORMAL, ARRAY, SKIP,
    } type;

    GIDirection direction;

    GIArgument data;
};

还有GIArgument定义:

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;

完整的文件可以在这里找到:https://gist.github.com/romgrk/642388914a9ff412eb5683fca44009d7#file-function-cc-L255

当我走到那一行时,我的 GDB 输出是:

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
  }
}

【问题讨论】:

  • 可能是 as-if 规则,如果该值未被使用,则不必存储它,例如Loop with a zero execution time
  • 问题是我稍后在代码中尝试使用该变量的值,但它没有分配给正确的值。是否有可能是 as-if 规则?
  • 我看到了一个叫_GIArgument的联合类型和一个GIArgument类型的结构成员,我们不知道它是什么。
  • 没有你调试的代码就不可能知道发生了什么......

标签: c++


【解决方案1】:

问题可能是len_param.data 没有做任何事情,除了在它超出范围和len_param 的生命周期到期之前获取它的地址。所以编译器认为在那里存储任何东西是没有意义的。

这是代码 sn-p,其中len_param 被定义、使用和终止(省略了不必要的代码并添加了一些注释 cmets):

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

根本问题是callable_arg_values[length_i].v_pointer 中的指针在存储后立即无效。

【讨论】:

  • 但是 len_param 不是对 call_parameters 元素的引用吗?
  • 根据您发布的内容,len_param 不是对任何内容的引用 - 它是 struct Parameter 类型的对象,其生命周期一直持续到声明它的块结束。它被初始化为成为call_parameters[length_i] 的副本。也许你需要做的就是把它变成一个参考:Parameter&amp; len_param = call_parameters[length_i];
  • 使用您在上一条评论中描述的参考起到了作用,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-20
  • 2012-05-07
  • 1970-01-01
  • 2014-01-12
相关资源
最近更新 更多