Prev: Warning to newbies
Next: Simple question on XML Schema
From: Dann Corbit on 16 Mar 2010 18:22 This fragment of code is from zlib: /* We check for insufficient lookahead only every 8th comparison; * the 256th check will be made at strstart+258. */ do { } while( *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && scan < strend); Now, the && operators are sequence points, so the behavior is not undefined. Assuming that scan and match are not aliased, is the result of all the side effects in the computation unspecified or not? At first I thought it was unspecified, but since all the assignments are identical I am pretty well convinced that the result is not unspecified, but I thought it would be good to ask the experts.
From: Ben Bacarisse on 16 Mar 2010 19:38 Dann Corbit <dcorbit(a)connx.com> writes: > This fragment of code is from zlib: > > /* We check for insufficient lookahead only every 8th comparison; > * the 256th check will be made at strstart+258. > */ > do { > } while( > *++scan == *++match && *++scan == *++match && > *++scan == *++match && *++scan == *++match && > *++scan == *++match && *++scan == *++match && > *++scan == *++match && *++scan == *++match && > scan < strend); > > > Now, the && operators are sequence points, so the behavior is not > undefined. I'm happy to take your word for it (you know the rest of the code) but from the fragment above the &&s do not, on their own, stop this being undefined (in the C sense of the word). This being c.u.p there may be other standards and/or assurances that the code relies on. > Assuming that scan and match are not aliased, is the result > of all the side effects in the computation unspecified or not? There are some things in the code that are "unspecified behaviour" as defined by C (for example the order of evaluation of some of the side expressions) but I'm not sure that is the sort of unspecified you mean. Using the C meaning, I don't see any scope for anything being unspecified in the results of the increments. > At first I thought it was unspecified, but since all the assignments are > identical I am pretty well convinced that the result is not unspecified, > but I thought it would be good to ask the experts. -- Ben.
From: Peter Nilsson on 17 Mar 2010 17:59 Dann Corbit <dcor...(a)connx.com> wrote: > This fragment of code is from zlib: > > /* We check for insufficient lookahead only every 8th > * comparison; the 256th check will be made at > * strstart+258. > */ > do { [I presume there's more code here, otherwise a plain while loop would make more sense.] > } while( > *++scan == *++match && *++scan == *++match && > *++scan == *++match && *++scan == *++match && > *++scan == *++match && *++scan == *++match && > *++scan == *++match && *++scan == *++match && > scan < strend); > > Now, the && operators are sequence points, so the behavior > is not undefined. Assuming that scan and match are not > aliased, is the result of all the side effects in the > computation unspecified or not? But match and scan can't be aliased unless there's macro play afoot. If they themselves alias, i.e. point to the same address, then there's still no harm reading that address twice and doing a comparison. The test, i == i is fine for most types [NANs aside.] > At first I thought it was unspecified, but since all the > assignments are identical The pointers match and scan are assigned (incremented) independantly. Unless they're the same object (which would require some macro play,) there's no harm incrementing each just once prior to a sequence point. Whenever the increment actually occurs is incidental since the result of ++x must yield the value of x + 1 (converted to the type of x.) > I am pretty well convinced that the result is not > unspecified, but I thought it would be good to ask > the experts. Then comp.lang.c is more obvious place to ask! ;) But it's difficult to know which aspect of this code you think is unspecified. None of the comparisons can be determined until runtime, and how many comparisons are made before one fails can also only be determined at runtime. But unless scan and match are pointers to types with trap representations then the result of the comparisons should be well defined. The code does presume that strend is a multiple of 8 ahead of scan. If that's not the case, then scan may run past the end of a buffer. Which would render the behaviour undefined. Are you talking about the case where scan and match are character pointers and comparison of 'random' extraneous (but present) bytes are made? If the pointers are unsigned char pointers, then the read values will indeed be unspecified if not previously assigned, but still usable in comparison, although the comparison may yield unintended (unspecified) results. If they are signed character pointers, then it is theoretically undefined if the implementation has trap representations for signed character types. The code does seem strange in the sense that it pre- increments scan but is compared strictly less than against strend.[ As if doing 'for (x = 1; x < 10;...' rather than 'for (x = 0; x < 10;...' or 'for (x = 1; x <= 10;...' which are more idiomatic. But then as I said, there's probably stuff inside the loop body which would make this make sense. Lastly, strend is okay as a 'variable' but is, at the very least, reserved for use as an external identifier. Identifiers begining str[a-z] are generally best avoided in C. -- Peter
|
Pages: 1 Prev: Warning to newbies Next: Simple question on XML Schema |