Old Microsoft C autoincrement bug
-
The setup: this is around 1990/91 timeframe. a short is 8 bits an int is 16 bits and a long is 32 bits. I may be a bit fuzzy on the array syntax but bear with me. The stack is an array of shorts on which the incoming value is pushed there is a corresponding pop routine.
static short Stack[256];
short pushonstack(short TheValue)
{
static short anothervariable;
static short stackPointer;/* more logic in here to manage the stack. The stack pointer is the return value */
stack\[stackpointer\] = theValue; return(stackpointer++);
}
What should have happened is that the stackpointer would be autoincremented and returned to the user. I checked the docs and autoincrement happened before the return (supposedly) what actually happened was the anothervariable value was incremented and an incorrect value for the stack pointer was returned. It seems that ALL non char variables in a return statement were treated as signed ints even unsigned and longs. Microsoft argued that the ISO spec required this but it turns out that it did not. Or the other way around, I'm not remembering real clearly at this point. It took quite a while to catch this one as the debuggers at the time were less than visual. Now from a best practices standpoint I don't think that using the autoincrement in the return statement is a good idea but theoreticaly it's legal. Just incidentaly on a motorla processor this bug would not have appeared. can you guess why?
-
The setup: this is around 1990/91 timeframe. a short is 8 bits an int is 16 bits and a long is 32 bits. I may be a bit fuzzy on the array syntax but bear with me. The stack is an array of shorts on which the incoming value is pushed there is a corresponding pop routine.
static short Stack[256];
short pushonstack(short TheValue)
{
static short anothervariable;
static short stackPointer;/* more logic in here to manage the stack. The stack pointer is the return value */
stack\[stackpointer\] = theValue; return(stackpointer++);
}
What should have happened is that the stackpointer would be autoincremented and returned to the user. I checked the docs and autoincrement happened before the return (supposedly) what actually happened was the anothervariable value was incremented and an incorrect value for the stack pointer was returned. It seems that ALL non char variables in a return statement were treated as signed ints even unsigned and longs. Microsoft argued that the ISO spec required this but it turns out that it did not. Or the other way around, I'm not remembering real clearly at this point. It took quite a while to catch this one as the debuggers at the time were less than visual. Now from a best practices standpoint I don't think that using the autoincrement in the return statement is a good idea but theoreticaly it's legal. Just incidentaly on a motorla processor this bug would not have appeared. can you guess why?
I'm gonna guess (and my memory of 68000 is rusty) that this is because the Motorola chip aligns the short.
Arthur Dent - "That would explain it. All my life I've had this strange feeling that there's something big and sinister going on in the world." Slartibartfast - "No. That's perfectly normal paranoia. Everybody in the universe gets that." Deja View - the feeling that you've seen this post before.
-
I'm gonna guess (and my memory of 68000 is rusty) that this is because the Motorola chip aligns the short.
Arthur Dent - "That would explain it. All my life I've had this strange feeling that there's something big and sinister going on in the world." Slartibartfast - "No. That's perfectly normal paranoia. Everybody in the universe gets that." Deja View - the feeling that you've seen this post before.
Pete O'Hanlon wrote:
I'm gonna guess (and my memory of 68000 is rusty) that this is because the Motorola chip aligns the short.
AFAIR, it's because the 68000 is big-endian, so when it performs the increment, it increments the correct byte...
Ryan
"Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
-
I'm gonna guess (and my memory of 68000 is rusty) that this is because the Motorola chip aligns the short.
Arthur Dent - "That would explain it. All my life I've had this strange feeling that there's something big and sinister going on in the world." Slartibartfast - "No. That's perfectly normal paranoia. Everybody in the universe gets that." Deja View - the feeling that you've seen this post before.
It is an alignment issue, in Intel a 16 bit value is stored lowbits highbits in motorola the other way around. And actually at the time the Motorola equivalent of the 8088/8086 was the 6809. There were adavantages for both processors to store the bytes that way. The motorola chip was the superior chip as it had a linear 16 bit address space and was capable of being clocked at nearly twice the speed of the intel chip. If Motorola had had a basic interpreter and rudimentary OS we would have had all motorola IBM PCs. Sadly OS9 was not complete enough to show IBM when they came asking so the execs said they had nothing. Bill Gates on the other hand, said here's our basic, and you want an OS , um well , here we have this one. (Quick Steve buy that OS from those guys over there). The rest is History.
-
The setup: this is around 1990/91 timeframe. a short is 8 bits an int is 16 bits and a long is 32 bits. I may be a bit fuzzy on the array syntax but bear with me. The stack is an array of shorts on which the incoming value is pushed there is a corresponding pop routine.
static short Stack[256];
short pushonstack(short TheValue)
{
static short anothervariable;
static short stackPointer;/* more logic in here to manage the stack. The stack pointer is the return value */
stack\[stackpointer\] = theValue; return(stackpointer++);
}
What should have happened is that the stackpointer would be autoincremented and returned to the user. I checked the docs and autoincrement happened before the return (supposedly) what actually happened was the anothervariable value was incremented and an incorrect value for the stack pointer was returned. It seems that ALL non char variables in a return statement were treated as signed ints even unsigned and longs. Microsoft argued that the ISO spec required this but it turns out that it did not. Or the other way around, I'm not remembering real clearly at this point. It took quite a while to catch this one as the debuggers at the time were less than visual. Now from a best practices standpoint I don't think that using the autoincrement in the return statement is a good idea but theoreticaly it's legal. Just incidentaly on a motorla processor this bug would not have appeared. can you guess why?
sbeckstead wrote:
What should have happened is that the stackpointer would be autoincremented and returned to the user. I checked the docs and autoincrement happened before the return (supposedly) what actually happened was the anothervariable value was incremented and an incorrect value for the stack pointer was returned.
I was wondering if you meant for example when entering the "pushonstack" function "stackPointer" variable is containing value zero. When returning from the "pushonstack" function in your code you were expecting return value of one? Of the alignment differences of that time I wouldn't know, in the '90 I wasn't yet into programming but for the return value in my opinion you should be getting the value of "stackPointer" variable before the auto increment in this case. The 'variable++' means that after the line is finished the increment happens -- and therefore the 'stackpointer' value in your example is copied to the return variable before the increment happens. ..then again if you just had a typo and meant to write '++stackpointer' in your example which should have given the incremented value as the return value.. ..anyhow not to be nitpicking, just to cause conversation :cool:
-
sbeckstead wrote:
What should have happened is that the stackpointer would be autoincremented and returned to the user. I checked the docs and autoincrement happened before the return (supposedly) what actually happened was the anothervariable value was incremented and an incorrect value for the stack pointer was returned.
I was wondering if you meant for example when entering the "pushonstack" function "stackPointer" variable is containing value zero. When returning from the "pushonstack" function in your code you were expecting return value of one? Of the alignment differences of that time I wouldn't know, in the '90 I wasn't yet into programming but for the return value in my opinion you should be getting the value of "stackPointer" variable before the auto increment in this case. The 'variable++' means that after the line is finished the increment happens -- and therefore the 'stackpointer' value in your example is copied to the return variable before the increment happens. ..then again if you just had a typo and meant to write '++stackpointer' in your example which should have given the incremented value as the return value.. ..anyhow not to be nitpicking, just to cause conversation :cool:
Probably correct. I know that after discovering the bug I researched the heck out of it and did conclude that the increment should have occurred before the return. It probably was the pre-increment rather than the post-increment operator. So ++stackpointer was probably the correct return. In either case treating a short as an int was the bug not the order of the increment. The stack pointer variables were probably global variables as well, my memory fades at this point. The incident sticks with me because of Microsoft's refusal to admit it was a bug. They actually said that it had been done that way by design. But while claiming compliance with the standard they were specifically designing their compiler to violate it. When I pointed this out I got a very terse letter from the program director stating that the matter was closed and please do not bring it up again. They eventually in a point release fixed it. Nit picking is probably a good habit for a programmer, It leads to less "detail oriented" mistakes. So yes a good conversation picker upper. Scott
-
It is an alignment issue, in Intel a 16 bit value is stored lowbits highbits in motorola the other way around. And actually at the time the Motorola equivalent of the 8088/8086 was the 6809. There were adavantages for both processors to store the bytes that way. The motorola chip was the superior chip as it had a linear 16 bit address space and was capable of being clocked at nearly twice the speed of the intel chip. If Motorola had had a basic interpreter and rudimentary OS we would have had all motorola IBM PCs. Sadly OS9 was not complete enough to show IBM when they came asking so the execs said they had nothing. Bill Gates on the other hand, said here's our basic, and you want an OS , um well , here we have this one. (Quick Steve buy that OS from those guys over there). The rest is History.
You also worked with Microware OS9? Wasnt it a perfect operation OS. I still think they were way ahead of their time, still now some of the concepts are much better than the things MS is doing now...
-
You also worked with Microware OS9? Wasnt it a perfect operation OS. I still think they were way ahead of their time, still now some of the concepts are much better than the things MS is doing now...
Yup I was a beta tester for Microware. I found so many bugs that they pulled me from the project. But my partner continued and it turned into a great OS. I ran a company on OS9 for about a year and it worked very well. Scott