468,457 Members | 1,598 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,457 developers. It's quick & easy.

Cannot compile with _FILE_OFFSET_BITS = 64

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?
Dec 31 '07 #1
13 6803
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.
Dec 31 '07 #2

"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.
Dec 31 '07 #3
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

Dec 31 '07 #4
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
Dec 31 '07 #5
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

Dec 31 '07 #6
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.
Dec 31 '07 #7
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 ---
Dec 31 '07 #8
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"
Dec 31 '07 #9
"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

Jan 1 '08 #10
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
Jan 1 '08 #11
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"
Jan 1 '08 #12
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.
Jan 1 '08 #13
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
Jan 1 '08 #14

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

1 post views Thread by Tony Johansson | last post: by
5 posts views Thread by sam.barker0 | last post: by
reply views Thread by NPC403 | last post: by
1 post views Thread by subhajit12345 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.