getc fgetc

  • Thread starter Bill Cunningham
  • Start date
B

Bill Cunningham

I wrote this little reader program I like. It's just for fun anyway but
what does it mean that getc can be implemented as a macro and be reused
while fgetc can't? The only difference I see in them is the f in front. Also
Where I used != in my code I tried using the ! and I was given an error.

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

int main(int argc, char *argv[])
{
int a;
FILE *fp;
if ((fp = fopen(argv[1], "r")) == NULL) {
fputs("fopen error\n", stderr);
exit(1);
}
while ((a = getc(fp)) != EOF)
putc(a, stdout);
return 0;
}

while((a = getc(fp)) !EOF)

I wrote the above and something was wrong.

Bill
 
F

Fred

    I wrote this little reader program I like. It's just for fun anyway but
what does it mean that getc can be implemented as a macro and be reused
while fgetc can't? The only difference I see in them is the f in front. Also
Where I used != in my code I tried using the ! and I was given an error..

The standard says that getc *may* (at the implementation's
discression)
be implemented as a macro rather that as a function, whereas
fgetc MUST be implemented as a function.

If getc is implemented as a macro, it may reference its argument
more than once.
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    int a;
    FILE *fp;
    if ((fp = fopen(argv[1], "r")) == NULL) {
        fputs("fopen error\n", stderr);
        exit(1);
    }
    while ((a = getc(fp)) != EOF)
        putc(a, stdout);
    return 0;

}

while((a = getc(fp)) !EOF)

I wrote the above and something was wrong.

Syntax error. What do you expect from:
(xxx) !EOF
 
B

Bill Cunningham

[snip]

Syntax error. What do you expect from:
(xxx) !EOF

I was thinking that ! is short for !=. But obviously I must not be using it
right.

Bill
 
K

Keith Thompson

Fred said:
The standard says that getc *may* (at the implementation's
discression)
be implemented as a macro rather that as a function, whereas
fgetc MUST be implemented as a function.

If getc is implemented as a macro, it may reference its argument
more than once.

Not quite. Any library function may additionally be implemented
as a macro, as long as that macro meets certain restrictions,
including that it must evaluate each of its arguments exactly once
(C99 7.1.4p1). Those restrictions are relaxed for getc, so that it
it's implemented as a macro, it may evaluate its stream argument
more than once. (The stream argument rarely has side effects, so
this doesn't create any great inconvenience for programmers, but
relaxing the requirement can make getc substantially more efficient.)

[...]
 
K

Keith Thompson

Bill Cunningham said:
I wrote this little reader program I like. It's just for fun anyway but
what does it mean that getc can be implemented as a macro and be reused
while fgetc can't? The only difference I see in them is the f in front. Also
Where I used != in my code I tried using the ! and I was given an error.
[snip]

while ((a = getc(fp)) != EOF)
putc(a, stdout); [snip]

while((a = getc(fp)) !EOF)

I wrote the above and something was wrong.

"while ((a = getc(fp)) != EOF)" is correct.
"while((a = getc(fp)) !EOF)" is wrong.
The compiler told you so.
What's the problem?
 
K

Keith Thompson

Bill Cunningham said:
[snip]

Syntax error. What do you expect from:
(xxx) !EOF

I was thinking that ! is short for !=. But obviously I must not be using it
right.

It's not.

For the umpteenth time, don't guess. Look up ! and != in whatever
reference you're using.

I think one of your problems is that you often guess at something
without realizing that you're guessing, which I suppose makes my
repeated "don't guess" advice not as useful as it might be. You need
to distinguish between things that you're sure of (and right about!)
and things that you're not sure of and need to check in some
reference. I'm not sure how to advise you to acquire that skill.
 
N

Nobody

Not quite. Any library function may additionally be implemented
as a macro, as long as that macro meets certain restrictions,
including that it must evaluate each of its arguments exactly once
(C99 7.1.4p1). Those restrictions are relaxed for getc, so that it
it's implemented as a macro, it may evaluate its stream argument
more than once. (The stream argument rarely has side effects, so
this doesn't create any great inconvenience for programmers, but
relaxing the requirement can make getc substantially more efficient.)

One point which your post doesn't make entirely clear:

Any library function may *additionally* be implemented as a macro, but it
still has to be implemented as a function; i.e. you can take its address
and call it indirectly, and you can #undef the macro to expose the
function declaration.

OTOH, getc() may be implemented solely as a macro, with no function.
 
K

Keith Thompson

Nobody said:
One point which your post doesn't make entirely clear:

Any library function may *additionally* be implemented as a macro, but it
still has to be implemented as a function; i.e. you can take its address
and call it indirectly, and you can #undef the macro to expose the
function declaration.

Right. I thought that the word "additionally", which I did use, made
that sufficiently clear.
OTOH, getc() may be implemented solely as a macro, with no function.

I don't think that's correct. C99 7.19.7.5p2 says:

The getc function is equivalent to fgetc, except that if it is
implemented as a macro, it may evaluate stream more than once, so
the argument should never be an expression with side effects.

The implementation is still required to implement getc as an actual
function.
 

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

Similar Threads

getc() != fgetc() ?? 3
Working with files 1
I'm facing a run-time error 14
neater code 14
comparison error 12
Program not giving any output 33
fgetc 37
write error 13

Members online

No members online now.

Forum statistics

Threads
473,965
Messages
2,570,148
Members
46,710
Latest member
FredricRen

Latest Threads

Top