首页 > 解决方案 > 当 int 和 long 相同时指针不兼容?

问题描述

在为 int 和 long 均为 32 位且 long long 为 64 位的平台编译 C 时(如 clang 或 gcc-m32或 clang 的 wasm32-unknown-wasi 目标),我收到有关不兼容指针类型的错误:

int32_t *i1 = NULL;
long *l1 = i1;
int64_t *i2 = NULL;
long *l2 = i2;
sizeof.c:13:11: warning: incompatible pointer types initializing 'long *' with an expression of type 'int32_t *' (aka 'int *') [-Wincompatible-pointer-types]
    long *l1 = i1;
          ^    ~~
sizeof.c:15:11: warning: incompatible pointer types initializing 'long *' with an expression of type 'int64_t *' (aka 'long long *') [-Wincompatible-pointer-types]
    long *l2 = i2;
          ^    ~~
2 warnings generated.

我觉得很奇怪,既不兼容int32_t也不int64_t兼容long。如果 int 和 long 相同,为什么会有警告?

标签: cpointerstypeswarningscompiler-warnings

解决方案


C 关于什么使类型兼容的规则部分是关于类型的“含义”,而不仅仅是它有多大,它代表什么值,或者它如何表示它们。在这些规则中,指向intand的指针long是不同且不兼容的类型,即使它们使用相同的字节数并以相同的方式编码地址,并且指向intlong使用相同的字节数并以相同的方式编码数字。

C 标准可能允许 C 实现(由typedef)定义,int32_t并视情况int64_tintlonglong long。在这种情况下,相应的类型不仅是兼容的,而且是相同的。然而,该标准还允许将它们定义为扩展类型,与基本整数类型不同,即使它们的功能相同。正如chqrlie 所指出的,您的 C 实现可能定义int32_t为 beintint64_tto be long long,因此两者都不兼容long.

类型的“意义”涉及到人类计划使用该类型的目的以及它对编译器的意义。int从某种意义上说,最初意味着与目标处理器的尺寸好,但随着时间的推移,这已经被削弱了。可以用相同的元素定义两种结构类型,但一种包含二维图的 xy 坐标,另一种包含复数的实部虚部。让这些独立且不兼容的类型有助于程序员避免一些错误。

总的来说,诸如int32_t x; int *p = &x;错误编写的代码,需要一个警告来指出这一点。并且警告不是障碍,因为很容易编写按需要运行的代码而不会收到警告。


推荐阅读