10 #define _FILE_OFFSET_BITS 64
11
12 int main(void) {
13 int fd;
14
15 if ((fd = open("file.hole", O_WRONLY | O_CREAT, 0664)) < 0) {
16 perror("open:");
17 exit(-1);
18 }
19
20 if (write(fd, "a", 1) != 1) {
21 perror("write:");
22 exit(-1);
23 }
24
25 if (lseek(fd, 4*1024*1024*1024, SEEK_SET) == -1) { // integer
overflow
26 perror("lseek:");
27 exit(-1);
28 }
29
30 if (write(fd, "A", 1) != 1) {
31 perror("write:");
32 exit(-1);
33 }
34
35 close(fd);
36
37 exit(0);
38 }
In this example, although I explicitly define _FILE_OFFSET_BITS 64, i
get the warning"integer overflow"
in the manual of lseek64, I saw this:
-------------------------------------------------------------------------------------------------
lseek
Prototype:
off_t lseek(int fd, off_t offset, int whence);
The library routine lseek() uses the type off_t. This is a
32-bit signed type on 32-bit architectures, unless one com-
piles with
#define _FILE_OFFSET_BITS 64
in which case it is a 64-bit signed type.
-------------------------------------------------------------------------------------------------
SO why i got such warning? 13 6944
On Mon, 31 Dec 2007 14:25:10 +0800, Scott.zhou wrote:
25 if (lseek(fd, 4*1024*1024*1024, SEEK_SET) == -1) { // integer
overflow
In this example, although I explicitly define _FILE_OFFSET_BITS 64, i
get the warning"integer overflow"
4 is an int. 1024 is an int. 1024 is an int. 1024 is an int. When you
multiply ints, you get an int, and the result must be within the range of
an int. Even if that int would later be converted to another type. You
first need to convert the 4 to a wider type, and then start multiplying.
"Scott.zhou" <rw*****@gmail.comwrote in message
news:fl**********@news.cn99.com...
10 #define _FILE_OFFSET_BITS 64
11
12 int main(void) {
13 int fd;
14
15 if ((fd = open("file.hole", O_WRONLY | O_CREAT, 0664)) < 0) {
16 perror("open:");
17 exit(-1);
18 }
19
20 if (write(fd, "a", 1) != 1) {
21 perror("write:");
22 exit(-1);
23 }
24
25 if (lseek(fd, 4*1024*1024*1024, SEEK_SET) == -1) { // integer
overflow
No automatic conversion to 64 bit type is done by compiler. So make it
explicit by making one of the constants as 64 bit type. This makes entire
expression 64 bit.
=4*1024*1024*1024LL // 64 Bit constant made by LL suffix.
Scott.zhou wrote roughly:
lseek64(fd, 4*1024*1024*1024, SEEK_SET) // integer overflow
Others already explained what is happening, but I'd suggest another approach
that works without C99's long long type simply cast the expression to
off_t, which will automatically be the correct 64 bit type, regardless of
whether you use C89 or C99.
In this example, although I explicitly define _FILE_OFFSET_BITS 64, i
get the warning"integer overflow" [...]
I hope you also understand where the problem comes from! The point has
nothing to do with lseek() but rather with how C handles arithmetic, in
particular that it doesn't suddenly switch to a bigger integer type.
Uli
In article <5t*************@mid.uni-berlin.de>,
Ulrich Eckhardt <do******@knuut.dewrote:
>lseek64(fd, 4*1024*1024*1024, SEEK_SET) // integer overflow
>Others already explained what is happening, but I'd suggest another approach that works without C99's long long type simply cast the expression to off_t, which will automatically be the correct 64 bit type, regardless of whether you use C89 or C99.
Casting the expression won't help, if it's already overflowed as an
int.
-- Richard
--
:wq
Richard Tobin wrote:
In article <5t*************@mid.uni-berlin.de>,
Ulrich Eckhardt <do******@knuut.dewrote:
>>lseek64(fd, 4*1024*1024*1024, SEEK_SET) // integer overflow
>>Others already explained what is happening, but I'd suggest another approach that works without C99's long long type simply cast the expression to off_t, which will automatically be the correct 64 bit type, regardless of whether you use C89 or C99.
Casting the expression won't help, if it's already overflowed as an
int.
Argh, well caught. Casting the first constant in above expression does the
job though.
Uli
Ravishankar S wrote:
"Scott.zhou" <rw*****@gmail.comwrote in message
news:fl**********@news.cn99.com...
....
> 25 if (lseek(fd, 4*1024*1024*1024, SEEK_SET) == -1) { // integer overflow
No automatic conversion to 64 bit type is done by compiler. So make it
explicit by making one of the constants as 64 bit type. This makes entire
expression 64 bit.
=4*1024*1024*1024LL // 64 Bit constant made by LL suffix.
That's not sufficient. The above is equivalent to
((((4*1024)*1024)*1024LL). The very first multiplication is safe; but
the second one might overflow, depending upon the value of INT_MAX. You
could solve this by moving the LL to the second 1024, but I think that's
an overly subtle solution; a maintenance programmer might not realize
why the exact position of the 'LL' is critical. I'd apply the LL suffix
to all 4.
Ulrich Eckhardt wrote:
Richard Tobin wrote:
>In article <5t*************@mid.uni-berlin.de>, Ulrich Eckhardt <do******@knuut.dewrote:
>>>lseek64(fd, 4*1024*1024*1024, SEEK_SET) // integer overflow Others already explained what is happening, but I'd suggest another approach that works without C99's long long type simply cast the expression to off_t, which will automatically be the correct 64 bit type, regardless of whether you use C89 or C99.
Casting the expression won't help, if it's already overflowed as an int.
Argh, well caught. Casting the first constant in above expression does the
job though.
Uli
You presume the first expression (4) will be evaluated before the last
(1024). Why?
--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
James Kuyper <ja*********@verizon.netwrites:
Ravishankar S wrote:
>"Scott.zhou" <rw*****@gmail.comwrote in message news:fl**********@news.cn99.com...
...
>> 25 if (lseek(fd, 4*1024*1024*1024, SEEK_SET) == -1) { // integer overflow
No automatic conversion to 64 bit type is done by compiler. So make it explicit by making one of the constants as 64 bit type. This makes entire expression 64 bit.
=4*1024*1024*1024LL // 64 Bit constant made by LL suffix.
That's not sufficient. The above is equivalent to
((((4*1024)*1024)*1024LL). The very first multiplication is safe; but
the second one might overflow, depending upon the value of
INT_MAX. You could solve this by moving the LL to the second 1024, but
I think that's an overly subtle solution; a maintenance programmer
might not realize why the exact position of the 'LL' is critical. I'd
apply the LL suffix to all 4.
Although lseek() is non-standard (it's POSIX, not standard C), I'll
mention that its second argument is of type off_t, which is not
necessarily the same as long long.
In the interest of writing what you actually mean, it might be better
to use a cast to off_t rather than the "LL" suffix. I'd also make the
value a named constant rather than a magic number:
#define THE_OFFSET ((off_t)4*1024*1024*1024)
...
if (lseek(fd, THE_OFFSET, SEEK_SET) == -1) {
...
Or you could apply the cast to all four constants, but if it's
isolated in a #define that's probably not as important.
The need for the conversion could be avoided by using a single literal
rather than a multiplication, but 4294967296 is a bit obscure. But
you *might* consider using 0x100000000. (Personally, I prefer the
cast.)
--
Keith Thompson (The_Other_Keith) <ks***@mib.org>
[...]
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
"Scott.zhou" wrote:
>
10 #define _FILE_OFFSET_BITS 64
11
12 int main(void) {
13 int fd;
14
15 if ((fd = open("file.hole", O_WRONLY | O_CREAT, 0664)) < 0) {
16 perror("open:");
17 exit(-1);
18 }
There is no such routine in std C as "open". There are no such
macros as O_WRONLY or O_CREAT. C programs that do i/o normally
require #include <stdio.h>, maybe more. -1 is not a valid argument
for exit (you can use 0 always, or EXIT_FAILURE or EXIT_SUCCESS
when you have #include <stdlib.h>.
Since your program is not standard C, it is off-topic here.
Consider using standard C routines, such as fopen.
--
Merry Christmas, Happy Hanukah, Happy New Year
Joyeux Noel, Bonne Annee, Frohe Weihnachten
Chuck F (cbfalconer at maineline dot net)
<http://cbfalconer.home.att.net>
--
Posted via a free Usenet account from http://www.teranews.com
In article <Rs6ej.35597$NL5.4320@trnddc05>,
James Kuyper <ja*********@verizon.netwrote:
>That's not sufficient. The above is equivalent to ((((4*1024)*1024)*1024LL). The very first multiplication is safe; but the second one might overflow, depending upon the value of INT_MAX.
Theoretically, but I doubt there's any implementation with 64-bit
lseek() and ints that can't hold 2^22.
>You could solve this by moving the LL to the second 1024, but I think that's an overly subtle solution; a maintenance programmer might not realize why the exact position of the 'LL' is critical. I'd apply the LL suffix to all 4.
I think using it on the first operand should be a recognisable idiom
to a competent C programmer.
-- Richard
--
:wq
CBFalconer <cb********@yahoo.comwrites:
"Scott.zhou" wrote:
>> 10 #define _FILE_OFFSET_BITS 64 11 12 int main(void) { 13 int fd; 14 15 if ((fd = open("file.hole", O_WRONLY | O_CREAT, 0664)) < 0) { 16 perror("open:"); 17 exit(-1); 18 }
There is no such routine in std C as "open". There are no such
macros as O_WRONLY or O_CREAT. C programs that do i/o normally
require #include <stdio.h>, maybe more. -1 is not a valid argument
for exit (you can use 0 always, or EXIT_FAILURE or EXIT_SUCCESS
when you have #include <stdlib.h>.
Since your program is not standard C, it is off-topic here.
Consider using standard C routines, such as fopen.
The problem he was having wasn't specific to the non-standard
functions he was using. He provided the prototype for the function on
which the error occurred. His actual problem had to do with an error
in an expression that used only standard constructs (and that problem
was solved some time ago).
--
Keith Thompson (The_Other_Keith) <ks***@mib.org>
[...]
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Richard Tobin wrote:
In article <Rs6ej.35597$NL5.4320@trnddc05>,
James Kuyper <ja*********@verizon.netwrote:
>That's not sufficient. The above is equivalent to ((((4*1024)*1024)*1024LL). The very first multiplication is safe; but the second one might overflow, depending upon the value of INT_MAX.
Theoretically, but I doubt there's any implementation with 64-bit
lseek() and ints that can't hold 2^22.
I am by nature a theoretician, and I don't know any reason why such an
implementation couldn't exist. Whether it does exist doesn't matter to
me; as long as it's possible for such an implementation to conform to
the relevant standards, one might eventually be created, even if there
are none in existence at this time. It's trivial to write code in such a
fashion that it would work on such an implementation, and I think the
code should therefore be so written.
>You could solve this by moving the LL to the second 1024, but I think that's an overly subtle solution; a maintenance programmer might not realize why the exact position of the 'LL' is critical. I'd apply the LL suffix to all 4.
I think using it on the first operand should be a recognisable idiom
to a competent C programmer.
Yes, but incompetent C programmers are commonplace, and from my past
experience I suspect that there is a good chance that sooner or later
one of them will be assigned to do maintenance work on some of my code.
It's not possible to make fool-proof code, fools are too ingenious.
However, it is possible to make code fool-resistant, and I do so
whenever the costs are not excessive.
In article <v1qej.2388$yv5.1985@trndny07>,
James Kuyper <ja*********@verizon.netwrote:
>Theoretically, but I doubt there's any implementation with 64-bit lseek() and ints that can't hold 2^22.
>I am by nature a theoretician, and I don't know any reason why such an implementation couldn't exist. Whether it does exist doesn't matter to me; as long as it's possible for such an implementation to conform to the relevant standards, one might eventually be created, even if there are none in existence at this time. It's trivial to write code in such a fashion that it would work on such an implementation, and I think the code should therefore be so written.
I suppose that depends on your aims. I've had to deal with computer
systems that were stupid in various ways. People had gone through
amazing contortions to make software run on them, and the unfortunate
result was that others ended up having to use them instead of better
machines. A system designed now with ints less than 32 bits would be
such a system. I'd rather such systems died for lack of use, so if I
have useful code I'd prefer that it didn't work on them.
-- Richard
--
:wq This discussion thread is closed Replies have been disabled for this discussion. Similar topics
1 post
views
Thread by Tony Johansson |
last post: by
|
8 posts
views
Thread by baustin75 |
last post: by
|
10 posts
views
Thread by Jean-David Beyer |
last post: by
|
5 posts
views
Thread by Bruce D |
last post: by
|
2 posts
views
Thread by mudge |
last post: by
|
reply
views
Thread by Tom |
last post: by
|
13 posts
views
Thread by hn.ft.pris |
last post: by
|
5 posts
views
Thread by wong_powah |
last post: by
|
5 posts
views
Thread by sam.barker0 |
last post: by
| | | | | | | | | | |