优化编译器的能力和局限性

影响1: 编译器
///////////////////////////////////////////////////////////////////////////
  1     #include <stdio.h>
  2
  3     void twiddle1(int *xp, int* yp)
  4     {
  5         *xp += *yp;
  6         *xp += *yp;
  7     }
  8     void twiddle2(int* xp, int* yp)
  9     {
 10         *xp += 2* *yp;
 11    }
 12
 13     int main()
 14     {
 15         int a1 = 2,b1 = 2;
 16         int a2 = 2,b2 = 2;
 17         int a3 = 2,b3 = 2;
 18         twiddle1(&a1,&b1);
 19         twiddle2(&a2,&b2);
  20         twiddle1(&a3,&a3);     //两个指针指向相同的地址
 21         twiddle2(&b3,&b3);    //两个指针指向相同的地址
 22         printf("%d %d\n%d %d\n",a1,a2,a3,b3);
 23         return 0;
 24     }
///////////////////////////////////////////////////////////////////////////
打印的结果如下:
6 6
8 6
twiddle2 函数本来是用来优化twiddle1 函数的,twiddle2 函数可以减少寄存器的访问次数,可是当地址相同时却产生了不同的结果,导致优化方案行不通。例如:
x = 1000, y = 3000;
*q = y;
*p = x;
t1 = *q;
此时 t1 的值的确定取决于 p 和 q 的地址是否相同。
//////////////////////////////////////////////////////////////////////////
  1 #include <stdio.h>
  2
  3 void swap(int* xp, int* yp)
  4 {
  5     *xp = *xp + *yp;
  6     *yp = *xp - *yp;
  7     *xp = *xp - *yp;
  8 }
  9 int main()
 10 {
 11     int a = 2;
 12     int b = 2;
 13     int c = 2;
 14     swap(&a,&b);
 15     swap(&c,&c);
 16     printf("a=%d b=%d c=%d\n",a,b,c);
 17     return 0;
 18 }
///////////////////////////////////////////////////////////////////////////
a=2 b=2 c=0
最后 c 的值为0
///////////////////////////////////////////////////////////////////////////
影响2:函数调用
////////////////////////////////////////////////////////////////
  1     #include <stdio.h>
  2     int count = 0;
  3     int fun()
  4     {
  5         return count++;
  6     }
  7
  8     int fun1()
  9     {
 10         return fun()+fun()+fun()+fun();
 11     }
 12     int fun2()
 13     {
 14         return 4*fun();
 15     }
 16     int main()
 17     {
 18         printf("%d\n",fun2());
 19         printf("%d\n",fun1());
 20         return 0;
 21     }
////////////////////////////////////////////////////////////////
函数的功能是相同的,可是却产生了副作用
0                // 4 * 0
10              // 1 + 2 + 3 = 6 因为先调用了一次fun2()所以count的值变为1,再调用fun2() 《=》 1+2+3+4 = 10;
这是函数调用带来的副作用,而大多数编译器是不会去检查函数有没有副作用的
////////////////////////////////////////////////////////////////

你可能感兴趣的:(优化编译器的能力和局限性)