which functions set the end-of-file indicator?

F

Flash Gordon

Barry Schwarz wrote, On 06/08/08 03:08:
CHAR_MIN is irrelevant since the only char at issue is unsigned char.
UCHAR_MIN, if it existed, would have to be 0. putc only puts unsigned
char. In the absence of an error, it will return the value of the
char that was put. That value is unsigned and therefore non-negative.
Since EOF must be negative, the only time EOF can be returned is when
an error is detected. In the case of an error, the value of the
original int to be put is irrelevant.

You have missed the point (although the bit about CHAR_MIN=EOF is
irrelevant I believe). To take a concrete example imagine an
implementation where CHAR_BIT is 16 and sizeof(int)==1 that uses 2s
complement. On this implementation

UCHAR_MAX==65535
INT_MAX=32767
EOF==-1

In the code you to

int ret = putc(EOF,stdout);

-1 is passed to putc.
putc converts it to an unsigned char giving a value of 65535
putc outputs 65535 to stdout (or the file of your choice)
put *attempts* to return 65535, but as it does not fit in an int
(greater than INT_MAX) it cannot. So putc returns the bit-pattern of all
16 bits set (as that is how 65535 is represented in an unsigned char on
this implementation).
All 16 bits set, when interpreted as a 16 bit 2s complement number
(which is what int is on this implementation) is -1.
Therefore, on this implementation, putc returns -1, which is the value
of EOF on this implementation, when -1 (the value of EOF) is passed in
and putc succeeds.

There have previously been long discussions here about whether such a
hosted implementation is conforming. There are definitely a lot of
freestanding implementations with sizeof(int)==1, but they are not
required to provide putc.
 
F

Flash Gordon

Barry Schwarz wrote, On 06/08/08 03:08:
CBFalconer said:
Richard Heathfield wrote:
CBFalconer said:
(e-mail address removed) wrote:
... snip ...
No it can be. We had a recent discussion about this and I think
everyone agreed that it's possible for EOF to be a valid byte.
Since EOF is a negative constant, it is hard to represent in an
unsigned char.
It is, however, trivial to convert EOF into an unsigned char.
However it is far from trivial to convert an unsigned char into
EOF.
That's impossible and makes no sense too.

The issue here is whether it makes sense to pass EOF to fputc or putc.
As they take an int expression for their first arguments, it is
possible to do so. That value is then converted inside [f]putc to an
unsigned char value and written to the stream specified. Then this byte
is cast to int and returned, if there are no write errors, in which
case EOF is returned.

When the unsigned char is converted back to an int, the value must be
non-negative.

Incorrect, see my other post for a specific example showing what happens
if sizeof(int)==1.
In that case it cannot be EOF which is guaranteed to be
negative. In the absence of an error, only non-negative values will
be returned. EOF is only returned on error.

Not that simple I'm afraid. See my other post.
Since you know this to be incorrect, then you know that the return
value will be non-negative in the absence of an error.

It doesn't allow the 2nd normally. However, if sizeof(int)==1 then about
half the values of an unsigned char (including EOF) cannot be
represented as an int, what does the implementation do with those?

See other post for a worked example.
 
N

nicolas.sitbon

When a file is opened via fopen(), what's the state of the end-of-file
and error indicator? undetermined? cleared? setted?
 
N

nicolas.sitbon

They are both cleared.

In fact, I find that :
7 When opened, a stream is fully buffered if and only if it can be
determined not to refer to
an interactive device. The error and end-of-file indicators for the
stream are cleared.

But what about append mode "a"? in this case what's the state of the
end-of-file indicator?
 
S

santosh

In fact, I find that :
7 When opened, a stream is fully buffered if and only if it can be
determined not to refer to
an interactive device. The error and end-of-file indicators for the
stream are cleared.

But what about append mode "a"? in this case what's the state of the
end-of-file indicator?

The end-of-file indicator for a file opened with mode "a" or "ab" is
irrelevant since input cannot be performed. When open with "a+" or
ab+", then presumably, end-of-file indicator is initially cleared.
 
R

Richard Bos

In fact, I find that :
7 When opened, a stream is fully buffered if and only if it can be
determined not to refer to an interactive device. The error and
end-of-file indicators for the stream are cleared.

But what about append mode "a"? in this case what's the state of the
end-of-file indicator?

Assuming you meant "a+", it's cleared; this becomes obvious once you
realise that the EOF indicator doesn't tell you that your next operation
will read past the end of the file (as it does in Pascal), but that the
previous one did.

Richard
 
N

nicolas.sitbon

Assuming you meant "a+", it's cleared; this becomes obvious once you
realise that the EOF indicator doesn't tell you that your next operation
will read past the end of the file (as it does in Pascal), but that the
previous one did.

Richard

thanks for explanation.
 
B

Barry Schwarz

Barry Schwarz wrote, On 06/08/08 03:08:

You have missed the point (although the bit about CHAR_MIN=EOF is
irrelevant I believe). To take a concrete example imagine an
implementation where CHAR_BIT is 16 and sizeof(int)==1 that uses 2s
complement. On this implementation

UCHAR_MAX==65535
INT_MAX=32767
EOF==-1

In the code you to

int ret = putc(EOF,stdout);

-1 is passed to putc.
putc converts it to an unsigned char giving a value of 65535
putc outputs 65535 to stdout (or the file of your choice)
put *attempts* to return 65535, but as it does not fit in an int
(greater than INT_MAX) it cannot. So putc returns the bit-pattern of all
16 bits set (as that is how 65535 is represented in an unsigned char on
this implementation).

In C99 (6.3.1.3-3), when a value is converted to a signed type in
which it will not fit, you get an implementation defined result or an
implementation defined signal. In C89 (3.2.1.2), the result is
implementation defined. What you describe can happen only if the
implementation documents it that way. I wonder if any do.
 
C

CBFalconer

When a file is opened via fopen(), what's the state of the
end-of-file and error indicator? undetermined? cleared? setted?

That depends on the state of the file (including existance) and the
options specified to fopen.
 
C

CBFalconer

Flash said:
.... snip ...

You have missed the point (although the bit about CHAR_MIN=EOF is
irrelevant I believe). To take a concrete example imagine an
implementation where CHAR_BIT is 16 and sizeof(int)==1 that uses
2s complement. On this implementation

UCHAR_MAX==65535
INT_MAX=32767
EOF==-1

In the code you to

int ret = putc(EOF,stdout);

-1 is passed to putc.
putc converts it to an unsigned char giving a value of 65535
putc outputs 65535 to stdout (or the file of your choice)
put *attempts* to return 65535, but as it does not fit in an int
(greater than INT_MAX) it cannot. So putc returns the bit-pattern
of all 16 bits set (as that is how 65535 is represented in an
unsigned char on this implementation). All 16 bits set, when
interpreted as a 16 bit 2s complement number (which is what int
is on this implementation) is -1. Therefore, on this
implementation, putc returns -1, which is the value of EOF on
this implementation, when -1 (the value of EOF) is passed in
and putc succeeds.

Error there. putc returns an int. In the above case the
conversion of 65535 to int exceeds the range of an int, and the
result is either implementation or undefined.
 
J

James Kuyper

CBFalconer said:
That depends on the state of the file (including existance) and the
options specified to fopen.

Citation, please?

7.19.5.3p7 simply says "The error and end-of-file indicators for the
stream are cleared." Is there a statement somewhere else in the standard
that makes the applicability of 7.19.5.3p7 dependent upon either the
state of the file and the options specified to fopen()?
 
S

santosh

CBFalconer said:
That depends on the state of the file (including existance) and the
options specified to fopen.

Is that so? I thought that the end-of-file and error indicators for a
stream that has been newly created are cleared initially.

Section 7.19.5.3 (para 7) from n1256 seems to say this is so.
 
C

CBFalconer

James said:
Citation, please?

7.19.5.3p7 simply says "The error and end-of-file indicators for
the stream are cleared." Is there a statement somewhere else in
the standard that makes the applicability of 7.19.5.3p7 dependent
upon either the state of the file and the options specified to
fopen()?

Woops. Guess I am using my Pascal knowledge in the wrong place.
There opening a file implies an initial read (for a read file), and
EOF is set for a write file.
 
R

Richard

CBFalconer said:
Woops. Guess I am using my Pascal knowledge in the wrong place.
There opening a file implies an initial read (for a read file), and
EOF is set for a write file.

Pascal knowledge?!?!?!?!

LOL
 
F

Flash Gordon

Barry Schwarz wrote, On 06/08/08 10:24:
In C99 (6.3.1.3-3), when a value is converted to a signed type in
which it will not fit, you get an implementation defined result or an
implementation defined signal. In C89 (3.2.1.2), the result is
implementation defined. What you describe can happen only if the
implementation documents it that way. I wonder if any do.

I'm not aware of any implementations that raise a signal but I am aware
of implementations where sizeof(int)==1. I also happen to know that the
one I used a lot would on converting from unsigned to signed just do a
re-interpretation of the bits and therefore 65535 *would* become -1 (as
it did not raise a signal this behaviour would have to be defined).
However, it was not a hosted implementation and so was not bound to
provide putc (or if providing it was not bound to provide one meeting
the requirements of putc on a hosted implementation).

<snip>
 
F

Flash Gordon

CBFalconer wrote, On 06/08/08 13:40:
Flash Gordon wrote:
... snip ...
^^^^^^^^^^^^^^^^^^^^^^

Error there.
No.

putc returns an int.

Yes, as I at least implied as why else would I be talking about the size
of int?
In the above case the
conversion of 65535 to int exceeds the range of an int, and the
result is either implementation or undefined.

So? I was *explicitly* talking about an implementation which does what I
described and by your own admission above an implementation is *allowed*
to define the behaviour. So unless you are claiming that an
implementation is not allowed to define the behaviour as being what
probably most implementations with sizeof(int)==1 actually do I don't
see your point.
 
C

CBFalconer

Flash said:
CBFalconer wrote, On 06/08/08 13:40:
.... snip ...


Yes, as I at least implied as why else would I be talking about
the size of int?


So? I was *explicitly* talking about an implementation which
does what I described and by your own admission above an
implementation is *allowed* to define the behaviour. So unless
you are claiming that an implementation is not allowed to define
the behaviour as being what probably most implementations with
sizeof(int)==1 actually do I don't see your point.

For example the system may crash, may signal, etc. The point is
that the action is not predictable and thus the code is not
portable.
 
A

Antoninus Twink

Pascal knowledge?!?!?!?!

LOL

Unbelievable, isn't it? I mean, you simply couldn't make it up: CBF
takes a view of topicality so strict that even Harold "the machine" van
Dijk slams him for narrow-mindedness, but then somehow thinks it's a
good idea to answer a question about C with information on file-handling
in Pascal. Incredible.
 
S

santosh

CBFalconer said:
For example the system may crash, may signal, etc. The point is
that the action is not predictable and thus the code is not
portable.

He never claimed that the code was portable. He was talking about a
particular case, a particular machine, that does define perfectly the
conversion of (unsigned char)EOF to an int, yielding EOF again.
 

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

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top