【问题标题】:Why casting short to void * get a warning, and from int it's okey?为什么将 short 转换为 void * 会收到警告,并且从里面可以吗?
【发布时间】:2011-03-31 11:17:38
【问题描述】:

看 我正在使用 glib,而 gpointer 是 void * 的 typedef。 (我猜 glib 做这种类型是为了让事情更清楚)。

当我进行信号连接时,我必须将数据作为 void 指针 (void *) 传递。

所以代码是(类似这样的):

...
g_signal_connect (object, function, (gpointer) data);
...

如果我使用 short 作为数据类型,我会收到这样的 gcc 警告消息:

警告:从整数转换为指针 大小不一

如果我使用 int 作为数据类型,我不会收到任何警告。

但是在这两种情况下,一切都运行良好,那么,为什么我使用 short 会收到此警告?

【问题讨论】:

  • 所以我必须先将它(或所有内容)转换为 int,然后再转换为 void 指针?

标签: c


【解决方案1】:

在 32 位架构上,指针是 32 位的。 int 通常也是 32 位 - 所以转换是“1 到 1”。 short 通常是 2 个字节,因此将 short 转换为指针通常不是很安全的事情 - 这就是编译器警告您的原因。

【讨论】:

    【解决方案2】:

    Gcc 告诉您将不同大小的整数转换为指针,这主要是危险的另一种方式(例如,从较大的数据类型转换为较小的数据类型)。要使警告静音,您可以使用 intptr_t 作为中间类型。

    g_signal_connect (object, function, (gpointer)(intptr_t) data);
    

    【讨论】:

      【解决方案3】:

      short 为 2 字节,指针取决于平台,但通常为 4 或 8 字节。这应该是您收到该错误的原因。您可能想要传递一个简短的参考,其中将是:

      (gpointer) &data);
      

      【讨论】:

      • 那么您需要在回调中取消引用它。即:短 s = *数据;
      • 但是如果data是一个局部变量,调用回调的时候就不存在了。他可能真的想通过data 而不是&data
      • 好点。我没有想到这一点。距离我上次使用 Gtk 和 C 已经有一段时间了。
      • 在这种情况下,可以通过将short 变量设为static 来解决。
      【解决方案4】:

      整数到指针的转换依赖于 C 中的实现。来自 ISO 标准:

      整数可以转换为任何指针类型。除非前面指定,否则结果是实现定义的,可能未正确对齐,可能不指向引用类型的实体,并且可能是陷阱表示。

      由于短(即有符号短)通常是 16 位,而 void * 指针通常在 32 位架构上是 32 位或在 64 位架构上是 64 位,GCC 必须决定如何填充额外的位。 GCC 实际做的是符号扩展短,即它将位 14 位 0 复制到指针的位 14 位 0,并将短的位 15 复制到剩余的高位(32 位的 31-15 -bit 指针,或 64 位指针的第 63-15 位。)如果稍后将指针转换回不同宽度的整数类型,符号扩展会保留该值。

      short s = -1; // i.e. -> 0xffff
      void *p = (void *)s; // on 32 bit system -> 0xffffffff
      

      如果符号扩展不是您想要的,也许您只是想要将 short 直接复制到指针的 15-0 位中。在这种情况下,你会做这样的事情:

      short s = -1; // i.e. -> 0xffff
      void *p = (void *)((unsigned short)s); // on 32 bit system -> 0x0000ffff
      

      【讨论】:

        猜你喜欢
        • 2019-05-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-16
        相关资源
        最近更新 更多