周六项目组加班赶进度发布版本,遇到一个奇怪的问题,根据代码分析必走的逻辑居然没有打印日志,简直有点怀疑人生了。恰好昨晚看APUE信号章节时有看到书中明确说明,如果不加volatile,就会导致开启编译优化时去除循环语句的问题。
最终根据提交记录发现有人将整个项目的编译选项由原来的O1修改为了O3,优化理由是:提高程序的执行速度。当然是用优化选项O3能够提高程序的执行速度,代码如果写的有问题,会导致意想不到的问题。有意思的是我追查了下代码改动记录,15年的时候就有人尝试将O1修改为O3,过了几天又改动回来,估计是搞不定各种奇奇怪怪的问题。
改编自APUE示例代码:

#include <time.h>
#include <stdio.h>

int main()
{
    //度量程序执行时间
    clock_t begin = clock();
    int i, j;

    volatile int  k;

    for (i = 0; i < 300000; i++)
    for (j = 0; j < 4000; j++)
        k += i * j;

    clock_t end = clock();
    double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
    printf("time spent %f\n",time_spent);
    return 0;
}

编译运行:

[root c++]#gcc -O1 -o volatile volatile.c
[root c++]#
[root c++]#./volatile
time spent 2.820308
[root c++]#
[root c++]#gcc -O3 -o volatile volatile.c
[root c++]#./volatile
time spent 2.777719

如果我们把上面代码中的volatile去掉,我们再按照两种方式编译运行:

[root c++]#gcc -O0 -o volatile volatile.c
[root c++]#./volatile
time spent 3.180162
[root c++]#gcc -O1 -o volatile volatile.c
[root c++]#./volatile
time spent 0.496720
[root c++]#gcc -O3 -o volatile volatile.c
[root c++]#./volatile
time spent 0.000003

编译选项O0-O1-O3,代码执行时间越来越短,到最后直接整个for循环被优化掉不执行了。
维基百科-Volatile变量