单目运算符的求值顺序/求值序列点的一个有关问题! 非常迷惑

单目运算符的求值顺序/求值序列点的一个问题! 非常迷惑!
我知道i++是先返回i再++
++i是自增了i再返回
因此

int i=1;
printf("%d\n",i++);

打印1,而

int i=1;
printf("%d\n",++i);

打印2.

但是下面的实验:

#include<stdio.h>
int main(void)
{
int i=1;
printf("%d\n",(i++)+(i++));//每个子表达式都先返回1,再自增。打印2,和我期待的一致
i=1;
printf("%d\n",(i++)+(++i));//打印4,我期待的结果是print(1+3),和期待一致
i=1;
printf("%d\n",(++i)+(i++));//打印4,我期待的结果是print(2+2),和期待的一致
i=1;
printf("%d\n",(++i)+(++i);//打印6,我期待的结果是print(2+3),和期待不一致
return 0;
}


唯一的问题是,我认为(++i)+(++i)先自增i得到2,第一次返回,然后再自增i得到3,第二次返回,两次返回的结果相加=5.但是实际上打印6

我用vc2012的debug/release以及GCC4.4.6都是这样的结果。这是为什么呢?
我的理解问题在哪里?

------解决方案--------------------
叹息
求值是求值 副作用是副作用 
没先后关系
先求值 再++的说法是错误的 

和副作用紧密相关的是序列点
printf("%d\n",(i++)+(i++));这里的 表达式(i++)+(i++)在2次读写i对象的中间没有序列点 
无法确定副作用什么时候完成 
结果无法确定
编译器完全可能出现 1+1 1+2 2+1 等等

以下雷同
------解决方案--------------------

i=1;
printf("%d\n",(++i)+(++i); // 3 +3  ; // 先自加 2次 再加法操作!

//看看置顶帖吧!

------解决方案--------------------
++的重载函数返回的应该是i的引用吧。
printf("%d\n",&(i));printf("%d\n",&(++i));得到的地址是一样的。

既然返回的是引用,即使是前面的先算,后面算的时候,也会改变前面的引用值。