【发布时间】:2017-01-21 10:51:52
【问题描述】:
static int* p= (int*)(&foo);
我只知道 p 指向代码段中的内存。
但我不知道这一行到底发生了什么。
我想也许它是一个指向函数的指针,但指向函数的格式是:
returnType (*pointerName) (params,...);
pointerName = &someFunc; // or pointerName=someFunc;
【问题讨论】:
static int* p= (int*)(&foo);
我只知道 p 指向代码段中的内存。
但我不知道这一行到底发生了什么。
我想也许它是一个指向函数的指针,但指向函数的格式是:
returnType (*pointerName) (params,...);
pointerName = &someFunc; // or pointerName=someFunc;
【问题讨论】:
您获取foo 的地址并将其转换为指向int 的指针。
如果foo 和p 属于不同类型,编译器可能会发出关于类型不匹配的警告。演员表是为了压制那个警告。
例如,考虑以下代码,它会导致编译器发出警告 (initialization from incompatible pointer type):
float foo = 42;
int *p = &foo;
这里foo 是float,而p 指向int。很明显 - 不同的类型。
类型转换使编译器将一个变量视为不同类型。您通过将新类型名称放在括号中来进行类型转换。在这里,我们将指向 float 的指针视为指向 int 的指针,警告将不再存在:
float foo = 5;
int *p = (int*)(&foo);
你也可以省略一对括号,它的意思是一样的:
float foo = 5;
int *p = (int*)&foo;
如果foo 是一个函数,问题也是一样的。我们在赋值右侧有一个指向函数的指针,在左侧有一个指向int 的指针。将添加一个强制转换以使指向函数的指针被视为int 的地址。
【讨论】:
foo 是一个函数而不是一个变量。现在怎么可能?
指向对象的类型的指针(即不是 void* 也不是 指向函数的指针)不能存储到指向任何其他类型的指针 没有强制转换的对象,除了类型相同的少数情况 预选赛除外。符合要求的编译器需要发布一个 如果该规则被破坏,则进行诊断。
除此之外,该标准允许编译器解释强制转换的代码 无意义的指针,除非代码有一些限制 正如所写的那样,这使得这些演员表基本上没有用,因为名义上 促进优化的目的。制定规则时,大多数 编译器可能会做大约一半的优化 在规则下被允许,但仍会明智地处理指针强制转换 因为这样做可能会花费理论上可能的 5% 优化。然而,今天,它对于编译器编写者来说更时尚 找出所有允许优化的情况 标准而不考虑它们是否有意义。
像 gcc 这样的编译器有一个选项 -fno-strict-aliasing 可以阻止这个 一种优化,无论是在它会带来很大好处的情况下,还是 风险很小,以及在几乎肯定会崩溃的情况下 代码并且不太可能提供任何真正的好处。如果他们会有所帮助 可以选择仅阻止后者,但我不知道有一个。因此,我的 建议是,除非你想在一个非常有限的子集中编程 丹尼斯里奇的语言,我建议瞄准 -fno-strict-aliasing 方言。
【讨论】: