关于溢出的一个有关问题

关于溢出的一个问题
计算函数x-y不产生溢出就返回1:
int tsub_ok(int x,int y)
{
      return tadd_ok(x,-y);
}

int tadd_ok(int x,int y)
{
      int sum = x+y;
      int neg_over = x<0 && y<0 &&sum>=0;
      int pos_over = x>=0 &&y>=0 && sum<0;
      return !neg_over && !pos_over;
}

问:对于tsub_ok(int x,int y),x,y取什么值时产生错误的结果?

答案是当y = TMin时,即补码的最小值时,-y也等于TMin,函数tadd_ok会认为只要x是负数,就会负溢出,实际上,x-y根本没有溢出。

求问为什么:函数tadd_ok会认为只要x是负数,就会负溢出
------解决方案--------------------
假设x=-1,y=TMin, x-y应该是不会溢出的。 但是当调用tsub_ok函数的时候, 有y=-y=TMin。 而此时x=-1,y=TMin, 调用tadd_ok函数, 由于y=TMin,对于tadd_ok函数来说,只要x为负数, 那么tadd_ok就会溢出, 其实x=-1,y=TMin相减是不溢出的, 所以当x=-1,y=TMin, 调用tsub_ok会产生错误的结果。。。
------解决方案--------------------
对学习编程者的忠告:
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步对应汇编一行!

VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)