sandeep <> writes:
> I am learning C from the K&R book. I have questions about Section 8.5
> ("an implementation of Fopen and Getc"). Although this section is UNIX(r)
> specific I think all my questions are really about standard C... so the
> ISO taliban can relax...
I see the smiley, but referring to those of us who prefer to
discuss ISO C as "taliban" is a bit insulting, don't you think?
(And yes, I know the word literally means "students", but I doubt
that that's what you meant.)
> 1> Look at this Macro
> #define feof(p) ((p)->flag & _EOF) != 0)
>
> My question is: feof is only specified to return 0 or not 0. There is no
> requirement for it to only return 0 or 1. So why the unnecessary "!= 0"
> to force it to be 0 or 1? This seems very inefficient, after all feof is
> likely to be called many times.
Yes, the "!= 0" could be omitted, but it's not likely to be a big deal.
Since it's a macro, a compiler is likely to omit the extra calculation
anyway.
And no, feof() isn't likely to be called many times in well written
code. The way to determine whether you've reached the end of an input
stream is by checking the result of the reading function (for example,
getc() returns the value EOF). *After* that's happened, you can call
feof() to determine whether you reached end-of-file or encountered an
error.
> 2> Here is another macro
> #define getc(p) (--(p)->cnt>=0 ?(unsigned char)*(p)->ptr++ :_fillbuf(p))
> Doesn't that _fillbuf(p) ought to be _fillbuf((p)), one bracket for the
> function call and one bracket to stop expansion of sideeffects in p?
No, extra parentheses aren't needed. As long as the name of the macro
parameter is immediately surrounded by parentheses (or brackets),
there's no problem with operator precedence.
And it's not about "expansion of side effects", it's about operator
precedence, i.e., which operators are associated with which operands.
Any side effects will occur anyway.
> 3> In a comment on that getc Macro, K&R say: "The characters are returned
> unsigned, which ensures that all characters will be positive". I don't
> really understand the point of this, I usually use char not unsigned char
> for characters. And in K&R, all strings are of type char* not unsigned
> char*.
>
> Also if sizeof(char) == sizeof(int) then the character (unsigned char)
> UCHARMAX will clash with EOF == -1 when it gets promoted to int.
getc() returns a result of type int, not char. For example, if
UCHAR_MAX is 255, then getc() will return the value 255 if you read a
'\xff' character, and the value -1 (assuming EOF==-1) if you encounter
the end of the stream or an error. They clash only if you store the
result in something smaller than an int. So don't do that.
See section 12 of the comp.lang.c FAQ,
<http://www.c-faq.com/stdio/index.html>, especially the first few
questions.
--
Keith Thompson (The_Other_Keith)
kst- <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"