应用编译器选项 -00 与 -03 在 clang 上调用 malloc 的不同输出
Different output calling malloc on clang applying compiler options -00 vs -03
以下代码 运行 编译器选项 -O3
vs -O0
结果不同的输出:
#include <stdlib.h>
#include <stdio.h>
int main(){
int *p = (int*)malloc(sizeof(int));
int *q = (int*)realloc(p, sizeof(int));
*p = 1;
*q = 2;
if (p == q)
printf("%d %d", *p, *q);
return 0;
}
我对结果感到非常惊讶。
使用 clang 3.4、3.5 编译 (http://goo.gl/sDLvrq)
使用编译器选项-O0
— 输出:2 2
使用编译器选项-O3
— 输出:1 2
这是一个错误吗?
有趣的是,如果我稍微修改一下代码
(http://goo.gl/QwrozF) 它的行为符合预期。
int *p = (int*)malloc(sizeof(int));
*p = 1;
在 gcc 上测试它似乎工作正常。
realloc
之后,p
不再有效。
假设两个分配都成功,q
指向已分配的内存区域,而 p
是无效指针。该标准将 realloc
和 free
视为释放例程,如果成功,指针持有的地址将无法再使用。如果由于某种原因调用 realloc
失败,原始内存仍然有效(但当然 q
不是,它是 NULL)。
尽管您比较了 p
和 q
,但您已经写入了一个无效的指针,所以所有的赌注都被取消了。
可能这里发生的是 O3
设置导致编译器忽略指针并仅替换内联数字。高度优化意味着编译器可以采取各种捷径并忽略语句,只要它保证相同的结果——条件是所有代码都定义良好。
以下代码 运行 编译器选项 -O3
vs -O0
结果不同的输出:
#include <stdlib.h>
#include <stdio.h>
int main(){
int *p = (int*)malloc(sizeof(int));
int *q = (int*)realloc(p, sizeof(int));
*p = 1;
*q = 2;
if (p == q)
printf("%d %d", *p, *q);
return 0;
}
我对结果感到非常惊讶。
使用 clang 3.4、3.5 编译 (http://goo.gl/sDLvrq)
使用编译器选项
-O0
— 输出:2 2使用编译器选项
-O3
— 输出:1 2
这是一个错误吗?
有趣的是,如果我稍微修改一下代码 (http://goo.gl/QwrozF) 它的行为符合预期。
int *p = (int*)malloc(sizeof(int));
*p = 1;
在 gcc 上测试它似乎工作正常。
realloc
之后,p
不再有效。
假设两个分配都成功,q
指向已分配的内存区域,而 p
是无效指针。该标准将 realloc
和 free
视为释放例程,如果成功,指针持有的地址将无法再使用。如果由于某种原因调用 realloc
失败,原始内存仍然有效(但当然 q
不是,它是 NULL)。
尽管您比较了 p
和 q
,但您已经写入了一个无效的指针,所以所有的赌注都被取消了。
可能这里发生的是 O3
设置导致编译器忽略指针并仅替换内联数字。高度优化意味着编译器可以采取各种捷径并忽略语句,只要它保证相同的结果——条件是所有代码都定义良好。