T.R | Title | User | Personal Name | Date | Lines |
---|
3541.1 | Briefly, customer is right. | WIBBIN::NOYCE | Pulling weeds, pickin' stones | Fri Apr 18 1997 09:33 | 16 |
| > int fseek(
> FILE *stream,
> long int offset, <---
> int whence);
>
> int p1, p2, len;
> p1 = litPointers[6] * 256 + litPointers[7];
> :
> fseek(LitFV, 2048 + p1, 0);
The compiler should compute litPointers[6]*256 + litPointers[7], and store
this value into p1. If the value doesn't fit in a signed int, the behavior
from this point onward is undefined. Then the compiler should compute
p1+2048 (as an int -- if it doesn't fit, behavior is undefined again). Then
the compiler should convert the result to the proper type for the call --
in this case, it should convert it to long int. Finally, it makes the call.
|
3541.2 | have I understood this? | GIDDAY::STRAUSS | talking through my binoculars | Sun Apr 20 1997 19:22 | 13 |
| Thanks for the quick response.
Just to be sure I understand this correctly ...
If the value in 2048 + p1 can be stored in a signed int, then the
compiler converts it to a long int before calling fseek?
If either litPointers[6]*256 + litPointers[7] or 2048 + p1 is too large
for an int, then the behaviour is undefined?
Hope I've got this right.
Thanks again
leon
|
3541.3 | Yes, you do understand it - what is the customer's problem? | DECC::MDAVIS | Mark Davis - compiler maniac | Mon Apr 21 1997 11:08 | 28 |
| Using V5.5, cxx compiles the following with no errors, and the generated
code looks correct:
typedef int FILE;
extern "C" int fseek(
FILE *stream,
long int offset, // <---
int whence);
int litPointers[10];
FILE *LitFV;
main(){
int p1, p2, len;
p1 = litPointers[6] * 256 + litPointers[7];
fseek(LitFV, 2048 + p1, 0);
}
Did the customer have a compile error or runtime error? Was the customer
getting an (unreported) overflow on the assignment to p1, which then made
the fseek find the incorrect item? (If so, this is a user error, since
the result is undefined according to the standard.) The simple solution is
to define p1 as a long int....
Mark Davis
c/c++ team
|
3541.4 | "long p1" only helps p1+2048 | WIBBIN::NOYCE | Pulling weeds, pickin' stones | Mon Apr 21 1997 11:42 | 9 |
| > Was the customer getting an (unreported) overflow on the assignment to p1,
> [...] The simple solution is to define p1 as a long int....
Well, no, Mark, if the calculation of P[6]*256+P[7] as an int overflows,
it's already too late. In addition to making p1 a long, you would need to
rewrite the expression to do the computation in 'long'. Changing 256 to
256L should be enough:
long p1;
p1 = litPointers[6] * 256L + litPointers[7];
|
3541.5 | Bill's correct (as always) | DECC::MDAVIS | Mark Davis - compiler maniac | Mon Apr 21 1997 11:47 | 2 |
| Though I guessed as to the type of litPointers - if they're already
declared "long", then it's only the assignment that truncates....
|
3541.6 | the real problem ... | GIDDAY::STRAUSS | talking through my binoculars | Mon Apr 21 1997 18:42 | 14 |
| Thanks everyone. I can now confidently explain to the customer that his
code has a potential problem.
Of course, this is not the _real_ problem ...
Ths customer believes he's discovered a bug in the way UNIX handles
file i/o buffers. The code fragment came from a program he wrote to
illustrate this.
I wanted to be sure that his code was good before I start picking the
UNIX kernel to pieces ;-)
Thanks again
leon
|
3541.7 | unsigned char litPointers[2048]; | GIDDAY::STRAUSS | talking through my binoculars | Mon Apr 21 1997 21:41 | 2 |
| BTW, for the record, litPointers is decalred as
unsigned char litPointers[2048];
|
3541.8 | before you throw too many stones... | WIBBIN::NOYCE | Pulling weeds, pickin' stones | Tue Apr 22 1997 09:31 | 8 |
| > p1 = litPointers[6] * 256 + litPointers[7];
With litPointers declared as an array of unsigned char, this code now
looks as if it's depending on big-endian data layout of some buffer.
Has this code previously run on little-endian machines (such as PC's)?
What is the source of the data in the litPointers array?
Just some things to think about...
|
3541.9 | yes! big-endian data | GIDDAY::STRAUSS | talking through my binoculars | Tue Apr 22 1997 21:19 | 29 |
| Thanks for the suggestion in .8!
The customer has told me that the code was originally developed
on SCO UNIX and run on SCO, Solaris, SunOS and PCs.
As you suspected, they've coded for a big-endian machine.
The customer tells me this about his data ...
> The file 'literals.tcr' consists of 1024 2-byte pointers, =
>followed by concatenated, non terminated character strings.
I'm still waiting for a copy of this 'literals.tcr' file.
Here's another code fragment to show how he reads litPointers from
'literals.tcr' ...
LitFV = fopen("literals.tcr", "r");
int IsErrM = 0;
if (LitFV)
{ fseek(LitFV, 0, 0);
fread(litPointers, 2048, 1, LitFV);
} else
IsErrM = 1;
Would it help if I posted the whole (270 line) test program?
Thanks for all the interest adn help so far.
leon
|
3541.10 | yes seeing the program would help | DECC::OUELLETTE | mudseason into blackfly season | Thu Apr 24 1997 20:34 | 1 |
| x86 PCs are little-endian. The others are of course big-endian.
|
3541.11 | need to fix test data before posting the code | GIDDAY::STRAUSS | talking through my binoculars | Mon Apr 28 1997 18:33 | 11 |
| The customer has just informed me that the test data
I was running through his program was suspect :-(
Once I get that straightened out, I'll post the program
and data (assuming of course that there really is a
problem)
Thanks again for the sustained interest in this issue.
Please stay tuned.
leon
|