c - 指针转换

标签 c pointers

我读到将一个类型的指针分配给另一个指向另一种类型的指针是非法的;例如,在这本书中:

C 如何编程第 7 版。页。 299

Common Programming Error 7.7 Assigning a pointer of one type to a pointer of another type if neither is of type void * is a syntax error.

或在此URL :

但是在C11标准中是这样写的:

A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned for the referenced type, the behavior is undefined. Otherwise, when converted back again, the result shall compare equal to the original pointer.

所以我明白,只有存在对齐问题时,行为才是未定义的。

事实上,像 GCC 4.8 或 cl 2013 这样的编译器只会发出来自不兼容指针类型赋值的警告。

void 指针不存在该异常。

所以:

int a = 10;
float b = 100.22f;

int *p_a = &a;
float *p_f = &b;

p_a = p_f; // NOT ILLEGAL but WARNING
p_f = p_a; // converted back again. it still works

void *v_p = p_a; // NOT ILLEGAL NO WARNING
p_a = v_p; // converted back again. it still works

我理解得好吗?还是我错过了什么?

附言 还有谁能给我看一个“对齐问题”的例子吗?

最佳答案

您可以将指针视为指向数据的内存偏移量,而不管它是什么类型。任何标准指针(不是智能指针)都有固定大小,具体取决于系统(32 位或 64 位)。所以你可以将它们相互分配,现代编译器会警告你危险的操作,但问题是当你试图取消引用不兼容类型的指针时。取消引用时,app 会查找指向类型对应的字节数,因此在下一个示例中

int b = 10;
int* pB = &b;
double* pA = pB;

在取消引用 pB 时你会得到 10(int 的大小是 4 个字节),在取消引用 pA 时你会得到垃圾或崩溃,因为接下来的 4 个字节(double 是 8 个字节)可以分配给另一个变量的内存空间。

结论:在将它们分配给彼此时跟踪指针类型,特别是如果您使用 void* 作为中介间接分配它们。 指针赋值合法不合法是编译器的事,老的没警告你。分配给 void* 不被视为“非法”可能是因为它是通用的、不可引用的指针类型(它具有 undefined reference 大小并且该限制是 c 语言限制),因此您不会像上面的示例那样收到错误。

关于c - 指针转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25622980/

相关文章:

c - 尝试附加共享内存的已用地址时出错

c - SCCS "what"字符串未被编译器优化掉

cJSON打印函数不向对象添加数字

c - 预处理器参数和在 C 中编译#ifndef#ifdef

c++ - 具有方法指针参数默认值的模板

swift - 转换一个快速字典([String :AnyObject] ) to a UnsafeMutablePointer

c - 嗨,有人可以告诉我以下代码的作用吗

客户端使用C使用TCP套接字将数据发送到端口

c++ - 使用指针查找不平衡括号之间字符的位置

c++ - 指向成员奇怪声明的指针