EOF

R

Richard Tobin

lak said:
why EOF has an -1 value.what's the purpose to make it as -1. can any
one tell answer for this?

It doesn't have to have the value -1. It has a negative value so that
it can be easily distinguished from real characters when returned from
getc() and the like.

-- Richard
 
L

lak

why EOF has an -1 value.what's the purpose to make it as -1. can any
one tell answer for this?
 
M

Mark Bluemel

lak said:
why EOF has an -1 value.what's the purpose to make it as -1. can any
one tell answer for this?

RTFM is an obvious answer. Hint: The logic is essentially the same as
that which stipulates that getchar() (etc) return int not char...

I picked up my copy of K&R (first edition, somewhat battered :) and
found that at the time that was written there were two common EOF
conventions, one of which could be handled by getchar() returning a char
rather than an int... (Of course it had its own problems).
 
C

CBFalconer

lak said:
why EOF has an -1 value.what's the purpose to make it as -1. can
any one tell answer for this?

The only requirement for EOF is that it be negative.
 
M

Martin Ambuhl

lak said:
why EOF has an -1 value.what's the purpose to make it as -1. can any
one tell answer for this?

It doesn't. It could be any negative integral constant expression. The
reason is simple: to make EOF an encoding other than those used for
legitimate characters. That is why functions (or macros) like fgetc,
getc, and getchar return ints instead of chars. Did you check the FAQ
(or an elementary textbook) before posting? It's a good idea to do so;
many people, even the sweetest on occassion, get quite steamed at
elementary questions already answered in the FAQ.
 
B

bluey

why EOF has an -1 value.what's the purpose to make it as -1. can any
one tell answer for this?

The actual answer is quite simple. you need to learn - as do many -
about the registers on the cpu itself. given that 0 in acsii is a
value (albiet a Null value) the only way a processor can see past this
is by checking the carry bit flag. by passing a -1 to the register it
can see a processor condition of carry (or not in this case0.
 
M

Martin Ambuhl

bluey said:
The actual answer is quite simple. you need to learn - as do many -
about the registers on the cpu itself. given that 0 in acsii is a
value (albiet a Null value) the only way a processor can see past this
is by checking the carry bit flag. by passing a -1 to the register it
can see a processor condition of carry (or not in this case0.

Either "bluey" is making a joke, which is in very poor taste since the
person asking the question may take him seriously, or he's an idiot. In
either case you should ignore his blathering.
 
K

Keith Thompson

bluey said:
The actual answer is quite simple. you need to learn - as do many -
about the registers on the cpu itself. given that 0 in acsii is a
value (albiet a Null value) the only way a processor can see past this
is by checking the carry bit flag. by passing a -1 to the register it
can see a processor condition of carry (or not in this case0.

Knowing about CPU registers is not necessary at all, or even
particularly helpful in this case.

fgetc() returns an int value which is either:
the next character read from the input stream (interpreted as an
unsigned char and converted to int;
or:
a distinct value, namely the value of the macro EOF, to indicate
end-of-file or an error condition.

The standard requires EOF to have a negative value. (It doesn't
require it to be -1; I've never heard of an implementation where it's
defined as anything other than -1, but I still wouldn't assume
anything beyond what the standard guarantees).

Since a valid unsigned char value can be any non-negative value in the
range 0 to UCHAR_MAX, it makes sense to use a negative value if you
need something distinct from all possible unsigned char values.

Note the cpomlete lack in this explanation of any mention of CPU
registers, condition codes, or carry bits. It's all about values, not
representations. And since most code checks whether the result is
equal (or unequal) to EOF, the fact that it's negative doesn't
typically even matter. The standard *could* have allowed EOF to be
defined as (UCHAR_MAX + 1), for example.
 
B

Ben Pfaff

bluey said:
The actual answer is quite simple. you need to learn - as do many -
about the registers on the cpu itself. given that 0 in acsii is a
value (albiet a Null value) the only way a processor can see past this
is by checking the carry bit flag. by passing a -1 to the register it
can see a processor condition of carry (or not in this case0.

This answer is, at best, at the wrong level of abstraction for
the question. At worst, it is incorrect and misleading. I would
advise the OP to disregard it.
 
R

Richard Heathfield

CBFalconer said:
The only requirement for EOF is that it be negative.

No, it must also have integral type. #define EOF -3.14159 would not be
conforming.
 
K

Keith Thompson

Richard Heathfield said:
CBFalconer said:

No, it must also have integral type. #define EOF -3.14159 would not be
conforming.

Specifically, it must expand to an integer constant expression with
type int and a negative value.

#define EOF (-1L)

would not be conforming. Nor would

#define EOF -1
 
C

Charlie Gordon

Keith Thompson said:
Knowing about CPU registers is not necessary at all, or even
particularly helpful in this case.

fgetc() returns an int value which is either:
the next character read from the input stream (interpreted as an
unsigned char and converted to int;
or:
a distinct value, namely the value of the macro EOF, to indicate
end-of-file or an error condition.

The standard requires EOF to have a negative value. (It doesn't
require it to be -1; I've never heard of an implementation where it's
defined as anything other than -1, but I still wouldn't assume
anything beyond what the standard guarantees).

Since a valid unsigned char value can be any non-negative value in the
range 0 to UCHAR_MAX, it makes sense to use a negative value if you
need something distinct from all possible unsigned char values.

Note the cpomlete lack in this explanation of any mention of CPU
registers, condition codes, or carry bits. It's all about values, not
representations. And since most code checks whether the result is
equal (or unequal) to EOF, the fact that it's negative doesn't
typically even matter. The standard *could* have allowed EOF to be
defined as (UCHAR_MAX + 1), for example.

That would have required that UCHAR_MAX < INT_MAX.

Interestingly, on architectures where UCHAR_MAX > INT_MAX, converting an
unsigned char to an int with a simple cast invokes undefined behaviour. On
architectures with non 2's complement, int can have fewer distinguishible
values than unsigned char. Even on 2's complement, EOF could be
undistinguishable from a valid char read from the stream.

The classic idiom:

int c;
while ((c = getc(fp)) != EOF) {
...
}

would need to be changed to:

int c;
while ((c = getc(fp)) != EOF || !feof(fp)) {
...
}

And still could not account for the exact contents of the stream.

How ugly!
 
C

Coos Haak

Op Thu, 20 Sep 2007 09:33:55 +0200 schreef Charlie Gordon:

That would have required that UCHAR_MAX < INT_MAX.

Interestingly, on architectures where UCHAR_MAX > INT_MAX, converting an
unsigned char to an int with a simple cast invokes undefined behaviour. On
architectures with non 2's complement, int can have fewer distinguishible
values than unsigned char. Even on 2's complement, EOF could be
undistinguishable from a valid char read from the stream.

The classic idiom:

int c;
while ((c = getc(fp)) != EOF) {
...
}

would need to be changed to:

int c;
while ((c = getc(fp)) != EOF || !feof(fp)) {
...
}

while ((c = getc(fp)) != EOF && !feof(fp)) {

As long c isn't EOF _and_ the end of the file is not yet reached ;-)
And still could not account for the exact contents of the stream.

How ugly!
Yes!
 
C

CBFalconer

Charlie said:
.... snip ...

int c;
while ((c = getc(fp)) != EOF || !feof(fp)) {
...
}

And still could not account for the exact contents of the stream.

How not? Your construct seems to me to work everywhere, since the
feof() is not called unless EOF == c, and thus does not slow up
operation. feof() is also called only after the possible getc that
reached EOF.
 
C

Charlie Gordon

Coos Haak said:
Op Thu, 20 Sep 2007 09:33:55 +0200 schreef Charlie Gordon:



while ((c = getc(fp)) != EOF && !feof(fp)) {

As long c isn't EOF _and_ the end of the file is not yet reached ;-)

No, this loop will stop if getc(fp) returns EOF, which is possible before
the end of stream if sizeof(char) == sizeof(int).

But my loop is indeed incorrect as it does not stop in case of a read error.

The loop could actually be written this way:

while (c = getc(fp), !feof(fp) && !ferror(fp)) {
...
}

But that makes it even uglier.
 
T

Tor Rustad

Keith Thompson wrote:

[...]
Note the cpomlete lack in this explanation of any mention of CPU
registers, condition codes, or carry bits. It's all about values, not
representations. And since most code checks whether the result is
equal (or unequal) to EOF, the fact that it's negative doesn't
typically even matter. The standard *could* have allowed EOF to be
defined as (UCHAR_MAX + 1), for example.

It is interesting to note, while EOF need to be negative, the value of
WEOF need not to, and could be e.g. (WCHAR_MAX + 1).
 
C

Coos Haak

Op Thu, 20 Sep 2007 18:36:55 +0200 schreef Charlie Gordon:
No, this loop will stop if getc(fp) returns EOF, which is possible before
the end of stream if sizeof(char) == sizeof(int).

But my loop is indeed incorrect as it does not stop in case of a read error.

The loop could actually be written this way:

while (c = getc(fp), !feof(fp) && !ferror(fp)) {
...
}

But that makes it even uglier.

So the shortcut evaluation of C is somewhat different from mathematical
logic. || is indeed somewhat prettier to the eye than &&. Thanks for
remembering me.
 
P

Peter J. Holzer

How not? Your construct seems to me to work everywhere,

Assume that int is 16 bits with a sign-magnitude representation and
unsigned char is also 16 bits. Then there are only 65535 different int
values, but 65536 different unsigned char values. So two different
unsigned char values will be mapped to the same int value (probably 0
and 32768 will both be mapped to 0) and cannot be distinguished any
more (immediately assigning c to an unsigned char variable may help,
though).

One could argue that such an implementation is not conforming, however.

hp
 
P

Peter J. Holzer

Op Thu, 20 Sep 2007 18:36:55 +0200 schreef Charlie Gordon:

So the shortcut evaluation of C is somewhat different from mathematical
logic.

How is that different from mathematical logic?

hp
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top