当我使用 gcc 7.3.0 编译此代码时,我收到“来自不兼容指针类型的赋值”。
int intVar = 1;
char* charPointer;
charPointer = &intVar;
printf("%d", *charPointer);
到目前为止一切顺利。我可以通过这样进行指针赋值来处理它:
charPointer = (char*)&intVar;
现在我的疑问是:第二种情况有何不同?如果我不将 charPointer 转换为 int*,例如将其增加 n 或取消引用它,我仍然可能会搞砸。那么为什么编译器在这两种情况下表现不同呢?他为什么要关心赋值期间指针类型不匹配?我只是想了解其背后的逻辑。
最佳答案
由于将 int *
类型随意更改为 char *
,编译器会警告潜在的陷阱。通过强制转换,编译器假定编码人员知道他们在做什么。
在 C 中,各种类型的指针可以存在于不同的位置,具有不同的大小并以不同的方式编码。
这对于所有对象指针都很常见(int*
、char *
、struct foo *
)共享相同的大小和编码,但一般来说,这不是必需的。
函数指针的大小与对象指针的大小不同的情况并不罕见。
char *
和 void *
共享相同的大小和编码,并且字符指针指向具有最低对齐要求的数据。将非 char*
对象指针转换为 char *
始终“有效”。反之亦然。导致未定义的行为 (UB)。
转换为非字符指针也存在抗锯齿的风险(编译器需要跟踪通过一种指针类型进行的数据更改是否反射(reflect)在另一种指针类型中)。可能会导致非常奇怪的未定义行为。> 更好的代码可以避免指针类型更改1,并且在需要时通过强制转换进行显式转换。
<小时/>1 异常(exception)情况包括在不存在对齐问题的情况下将对象指针更改为 void *
或形式 void*
。
关于C 指针 : Assignment from incompatible pointer type,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55230477/