【发布时间】:2015-06-03 03:04:17
【问题描述】:
我在 GCC 4.8.2 中遇到了一个带有 -O2 的奇怪优化,它删除了一个函数。
见以下代码。
increase() 和 increase2() 是一样的,只是后者多了一个 printf()。
但是,如果在 GCC 中使用 -O2,则会删除 increase()。
#include <stdio.h>
#include <stdint.h>
#include <arpa/inet.h>
void swap(uint64_t *vector)
{
uint32_t *p = (uint32_t *)vector;
uint32_t tmp = p[0];
p[0] = htonl(p[1]);
p[1] = htonl(tmp);
}
void increase(uint64_t *vector)
{
swap(vector);
(*vector)++;
swap(vector);
}
void increase2(uint64_t *vector)
{
swap(vector);
(*vector)++;
printf("touch...\n");
swap(vector);
}
int main()
{
uint64_t vector = 0xa;
increase(&vector);
printf("%lx\n", vector);
increase2(&vector);
printf("%lx\n", vector);
return 1;
}
输出是:
a
touch...
10000000000000a
为什么?
提前致谢
对不起,我没有说清楚。
问题不是“删除函数”,而是“函数不影响参数”。
Matt McNabb 指出了原因,严格的别名规则。 非常感谢。
【问题讨论】:
-
我没有看到您描述的问题。似乎
increase()和increase2()都被调用了......有什么问题? -
了解如何使用 gnu 调试器逐步查看执行情况。
-
@WedaPashi 老实说,优化代码的调试对于初学者来说是相当混乱的。在这种特定情况下,甚至
main操作也会重新排序。另一方面,当然知道gdb是合理的。 -
你能检查一下你是否真的在运行这段代码,并且你没有,比如说,每次调用
printf之前increase? -
@dlask:非常正确。我完全同意你的看法。但是,我怀疑这是否会成为这个特定代码的问题,因为输出是否符合预期,Undefined Behaviour。我个人认为看到代码的步骤即执行和实际调试之间存在细微差别。看到代码的逐步执行确实可以帮助人们理解代码流,但不一定是在某些问题的情况下。
标签: c gcc optimization