在下面的代码中,
apb
和apb->amp
都是指针,指向malloc地址。
现象是apb->amp=NULL
会被优化,不会被执行,但是当我删除free(apb)
时,对apb->amp
的赋值不会被优化。
if (apb) {
if (apb->amp) {
free(apb->amp);
apb->amp = NULL;
}
free(apb);
}
我检查了gcc的优化选项,通过实验发现是优化选项“
-ftree-dse
”导致的:
-ftree-dse
对树木执行死库消除 (DSE)。死存储是指存储到某个内存位置,随后在没有任何干预加载的情况下被另一个存储覆盖。在这种情况下,可以删除较早的存储。该标志默认在 -O1 及更高级别启用。
我知道这段代码逻辑有问题。 apb被释放后,apb指向的地址就不能再使用了。 问题是(我对此很好奇):编译器如何知道 free 函数的语义并针对这种情况进行优化?编译器是否也能识别其他函数的语义并对其进行优化?
编译器如何知道 free 函数的语义并针对这种情况进行优化?编译器是否也能识别其他函数的语义并对其进行优化?
free
函数在C标准中指定了语义。编译器可以简单地使用它来对该特定函数的语义做出假设,方法是通过在编译器中特殊处理硬编码的特定函数,或者使用附加到 free
声明的某些编译器内置函数或属性。 C 库来指示其特定行为。
编译器也使用 C 标准库中的函数规范来对其他情况下的优化进行特殊处理,无论编译器开发人员认为值得实现特殊处理的情况。