> This seems to be a bug in gcc. The off_t argument to lseek is a 64-bit > type, but instead of being sign-extended to 64 bits, the value passed > (-sizeof(data)) passed is only extended to 32-bits, so is actually > +4294967292.
No, it is not a bug in gcc. Read a good book on C, please. > > If you write: > int n = -sizeof(data); > lseek(fd, n, SEEK_END); > it works as expected. Mostly right, because there you are promoting a signed 32-bit number to a signed 64-bit number, which sign-extends. However, that approach is risky - if you have a file that is bigger than 2 GB, you will not get the correct result, because negation of an unsigned greater than 2GB results in a positive signed 32-bit value less than 2GB, instead of the intended negative 64-bit value with absolute value greater than 2GB. The safer fix is to call: lseek(fd, -(off_t)sizeof(data), SEEK_END); That is, perform the negation after the sign extension, instead of beforehand, since you know that 32-bit unsigned to 64-bit signed 0-extends, but that sizeof(data) is intended to be positive anyway, and 64-bit signed negation of a positive number is guaranteed to be safe. -- Eric Blake -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/