【问题标题】:Pointer conversions指针转换
【发布时间】:2014-09-02 12:03:37
【问题描述】:

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

C 如何编程 7 ed。页。 299

常见编程错误 7.7 将一种类型的指针分配给 如果两者都不是 void * 类型,则另一种类型的指针是一种语法 错误。

或者在这个URL:

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

指向对象类型的指针可以转换为指向对象类型的指针 不同的对象类型。如果结果指针不正确 为引用类型对齐,则行为未定义。 否则,当再次转换回来时,结果将比较相等 到原来的指针。

所以我明白,只有当存在对齐问题时,行为才会被定义。

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

空指针不存在该异常。

所以:

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

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

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

【问题讨论】:

  • 也许您可以告诉我们这些“很多书”是什么,以及它们实际上在说什么?以及您使用的是什么版本的 gcc,以及它给出的警告。并告诉我们您对对齐做了哪些研究,以及您不了解哪些方面。
  • @Useless,我不明白将指向类型的指针分配给指向另一种类型的指针是合法的还是不像 void * 那样。对于标准,它似乎理解它是合法的......
  • 如果书中说将指针分配给另一个不同类型的指针是“语法错误”,那么这本书是错误的!
  • 我认为那是Deitel & Deitel 的书?无论如何,这显然是错误的。

标签: c pointers


【解决方案1】:

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

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

在取消引用 pB 时,您将获得 10(int 的大小为 4 个字节),而在取消引用 pA 时,您将收到垃圾或崩溃,因为接下来的 4 个字节(双精度为 8 个字节)可以分配给另一个变量的内存空间。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-20
    • 2012-10-24
    • 2016-08-24
    • 2022-01-18
    • 2016-05-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多