c - 当 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 相同,为什么会有警告?
解决方案
C 关于什么使类型兼容的规则部分是关于类型的“含义”,而不仅仅是它有多大,它代表什么值,或者它如何表示它们。在这些规则中,指向int
and的指针long
是不同且不兼容的类型,即使它们使用相同的字节数并以相同的方式编码地址,并且指向int
和long
使用相同的字节数并以相同的方式编码数字。
C 标准可能允许 C 实现(由typedef
)定义,int32_t
并视情况int64_t
为int
、long
或long long
。在这种情况下,相应的类型不仅是兼容的,而且是相同的。然而,该标准还允许将它们定义为扩展类型,与基本整数类型不同,即使它们的功能相同。正如chqrlie 所指出的,您的 C 实现可能定义int32_t
为 beint
和int64_t
to be long long
,因此两者都不兼容long
.
类型的“意义”涉及到人类计划使用该类型的目的以及它对编译器的意义。int
从某种意义上说,最初意味着与目标处理器的尺寸好,但随着时间的推移,这已经被削弱了。可以用相同的元素定义两种结构类型,但一种包含二维图的 xy 坐标,另一种包含复数的实部虚部。让这些独立且不兼容的类型有助于程序员避免一些错误。
总的来说,诸如int32_t x; int *p = &x;
错误编写的代码,需要一个警告来指出这一点。并且警告不是障碍,因为很容易编写按需要运行的代码而不会收到警告。
推荐阅读
- android - 通知仅显示在顶部栏中
- reactjs - 使用 hookrouter 反应 Material UI Button 组件
- shiny - 将shinyWidgets添加到R中的数据表中
- c++ - 是否可以通过指向不同的、不相关的子对象的指针来获取指向一个子对象的指针?
- node.js - Postgres 简单查询失败,没有错误
- html - 使 flexbox 项目宽度等于兄弟元素的组合宽度
- sql - 联合查询减去总数
- javascript - 将 jquery 中的默认值放入 textarea 时缺少 \
- git - 新文件夹中的哪些文件将由 git 添加
- visual-studio-code - VS Code editor.overviewRulerLanes 设置有什么作用?