which functions set the end-of-file indicator?

V

vippstar

Dunno if we're using different words or not, but
putc certainly can return EOF.

The end of file indicator has nothing to do with the EOF macro.
When putc returns EOF, it means one of the following

o error with the stream; ferror() should return non-zero.
o EOF is a valid byte value that has been written to the stream.

Mr Sosman is talking about file streams that feof() returns non-zero
for. (ie the eof flag is set).
putc cannot set that flag.
 
K

Keith Thompson

Dunno if we're using different words or not, but
putc certainly can return EOF.

Certainly.

Returning EOF and setting the end-of-file indicator are two different
things.

Concretely:

before = feof(stdout);
putc_result = putc('x');
after = feof(stdout);

It can be the case that putc_result == EOF, but it cannot be the case
that before==0 and after!=0.
 
J

James Kuyper

Eric said:
I'd say that's the commonsense view. In fact, I *did* say
that's the commonsense view. Not sure what the argument's about ...

I'm disagreeing with your assertion that the standard doesn't define
what input functions are. I'm disagreeing that your implication that you
are forced to fall back on commonsense in order to come up with a
definition. In my opinion, in a discussion about what the standard
means, citation of common sense rather than the actual words of the
standard indicates that either the standard has a defect, or your
argument has a defect.
 
C

CBFalconer

Greg said:
Dunno if we're using different words or not, but
putc certainly can return EOF.

Returning EOF signals error, not setting of end-of-file indicator.
 
B

Barry Schwarz

The end of file indicator has nothing to do with the EOF macro.
When putc returns EOF, it means one of the following

o error with the stream; ferror() should return non-zero.
o EOF is a valid byte value that has been written to the stream.

The second case cannot be. EOF is guaranteed to be negative. While
it is certainly possible to pass this value to putc, it will be
converted to unsigned char (7.19.7.8-2 and 7.19.7.3-2). It is this
positive value which will be returned, not EOF.
 
S

santosh

Barry said:
The second case cannot be. EOF is guaranteed to be negative. While
it is certainly possible to pass this value to putc, it will be
converted to unsigned char (7.19.7.8-2 and 7.19.7.3-2). It is this
positive value which will be returned, not EOF.

And here is a test program as well:

#include <stdio.h>
#include <stdlib.h>

int main(void) {
int retval = 0, rc = 0;
puts("Writing EOF to stderr with putc...");
retval = putc(EOF, stderr);
if (retval == EOF) {
printf("\nputc returned EOF. Value is: %d\n", retval);
if (ferror(stderr)) {
puts("Error indicator for stderr set.");
rc = EXIT_FAILURE;
}
} else printf("\nputc returned: %d\n", retval);
return rc;
}

$ ./a.out
Writing EOF to stderr with putc...
?
putc returned: 255
$
 
V

vippstar

The second case cannot be. EOF is guaranteed to be negative. While
it is certainly possible to pass this value to putc, it will be
converted to unsigned char (7.19.7.8-2 and 7.19.7.3-2). It is this
positive value which will be returned, not EOF.

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.

google thread
<http://groups.google.com/group/comp.lang.c/browse_thread/thread/
9047fe9cc86e1c6a/d5b9489e0b16a415>
or use the message id
<c9241d9e-3b73-450e-a012-5a5ab6f204f0@e39g2000hsf.googlegroups.com>
 
V

vippstar

Barry said:
On Aug 5, 3:40 am, (e-mail address removed) (Greg Comeau) wrote:



And here is a test program as well:

<snip>

Test programs like this are meaningless.
It's like claiming that CHAR_BIT is 8 and then writing a test program
to back up the claim...
See my response to Mr Schwarz about EOF and putc.
 
S

santosh

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.

google thread
<http://groups.google.com/group/comp.lang.c/browse_thread/thread/
9047fe9cc86e1c6a/d5b9489e0b16a415>
or use the message id
<c9241d9e-3b73-450e-a012-5a5ab6f204f0@e39g2000hsf.googlegroups.com>

Are you specifically claiming that a call to fputc/putc with EOF as it's
first argument will return EOF if a call to ferror on the stream
immediately after the fputc/putc call returns zero?
 
C

CBFalconer

.... 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.
 
C

CBFalconer

Richard said:
CBFalconer said:

It is, however, trivial to convert EOF into an unsigned char.

However it is far from trivial to convert an unsigned char into
EOF.
 
S

santosh

CBFalconer said:
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.

I think the issue is whether both of these two (simplified)
implementations of fputc are correct, as per the Standard:

int fputc(int ch, FILE *s) {
if (write((unsigned char)ch, s) == SUCCESS) return (unsigned char)ch;
else { s->err_flag = 1; return EOF; }
}

int fputc(int ch, FILE *s) {
if (write((unsigned char)ch, s) == SUCCESS) return ch;
else { s->err_flag = 1; return EOF; }
}

I think that the Standard doesn't allow the second implementation. The
relevant part is 7.19.7.3 of n1256.
 
K

Keith Thompson

CBFalconer said:
However it is far from trivial to convert an unsigned char into
EOF.

You just need an implementation where sizeof(int)==1 (which implies
CHAR_BIT>=16). (I'm ignoring the possibility of padding bits.)
 
B

Barry Schwarz

5On said:
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.
No one said EOF could not be a valid byte. However, putc will never
put a negative value. In the absence of an error, putc returns the
value it puts. Therefore, in the absence of an error, it must return
a positive value. Since EOF is negative, putc cannot return EOF other
than as an error indicator.

It will never return EOF as the value of the byte written. That is
what you claimed as the second case and it cannot be. More to the
point, putc will never write a negative value since each byte is
converted to unsigned char. Read the second section of the standard I
reference above.
 
V

vippstar

5On Tue, 5 Aug 2008 05:32:36 -0700 (PDT), (e-mail address removed) wrote:





No one said EOF could not be a valid byte. However, putc will never
put a negative value. In the absence of an error, putc returns the
value it puts. Therefore, in the absence of an error, it must return
a positive value. Since EOF is negative, putc cannot return EOF other
than as an error indicator.

It will never return EOF as the value of the byte written. That is
what you claimed as the second case and it cannot be. More to the
point, putc will never write a negative value since each byte is
converted to unsigned char. Read the second section of the standard I
reference above.

I'm not convinced. Read the discussion in my message that you snipped.
I don't think you understand the situation I'm talking about.
 
C

CBFalconer

santosh said:
CBFalconer said:
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.

Nit time. Your analysis is flawed. Notice that in the prototype:

int fputc(int ch, FILE *f);

ch is defined as an int. The conversion to int occurs before the
function is called. So fputc never sees a ch, and never converts
any such.
 
C

CBFalconer

Richard said:
CBFalconer said:
santosh wrote:
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.

Nit time. Your analysis is flawed. Notice that in the prototype:

int fputc(int ch, FILE *f);

ch is defined as an int. The conversion to int occurs before the
function is called. So fputc never sees a ch, and never converts
any such.

santosh claimed that, inside [f]putc, the value is converted /to an
unsigned char value/, and that is a perfectly correct claim.
.... trim justification ...

You have incorrectly "corrected" santosh. In such circumstances, an apology
is traditional in this newsgroup.

Alright. Apology tendered. It WAS a nit.
 
B

Barry Schwarz

CBFalconer said:
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. 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.
I think the issue is whether both of these two (simplified)
implementations of fputc are correct, as per the Standard:

int fputc(int ch, FILE *s) {
if (write((unsigned char)ch, s) == SUCCESS) return (unsigned char)ch;
else { s->err_flag = 1; return EOF; }
}

int fputc(int ch, FILE *s) {
if (write((unsigned char)ch, s) == SUCCESS) return ch;
else { s->err_flag = 1; return EOF; }
}

I think that the Standard doesn't allow the second implementation. The
relevant part is 7.19.7.3 of n1256.

Since you know this to be incorrect, then you know that the return
value will be non-negative in the absence of an error.
 
B

Barry Schwarz

Not even when CHAR_MIN<=EOF and UCHAR_MAX>INT_MAX?

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.
 
B

Barry Schwarz

I'm not convinced. Read the discussion in my message that you snipped.
I don't think you understand the situation I'm talking about.

Your text claims it is possible for putc to return EOF when it is
passed the int value EOF and successfully writes to the stream. If
that is not what you meant, then you need to correct your text so we
can all discuss what you really meant.

putc will never write the value EOF to the stream. It will write the
value (unsigned char)EOF. Whether you are convinced or not is
irrelevant; that is what 7.19.7.3-2 says it will do. (On those
systems where EOF is -1 and CHAR_BIT is 8, (unsigned char)EOF has the
value 255.) Therefore, it will return the value (unsigned char)EOF.
This value cannot compare equal to EOF.
 

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,768
Messages
2,569,575
Members
45,054
Latest member
LucyCarper

Latest Threads

Top