fopen modes

  • Thread starter Bill Cunningham
  • Start date
H

Hallvard B Furuseth

Nick said:
I tried arguing once that FILE didn't have to be a struct. But one
of the Powers (I *think* Chris Torek) pointed out that it would be
difficult (I paraphrase) for it not to be a struct. He pointed
out that some of the low level calls (eg. getc) are required to be
implemented as both a macro and a function

If that was it, said power was doubly confused.
"#define getc(x) fgetc(x)" or even "#define getc(x) getc(x)"
would satisfy such a requirement. However:

C99 7.19.7.5 The getc function:
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.
C89 has the same paragraph.
and (if I recall correctly)
the wording of The Standard almost forced it to be a struct.

The wording of something else in it, perhaps. There are a lot of words
there:)
 
C

Chris Dollin

jameskuyper said:
Chris Dollin wrote:
...

I've seen people do that (with a reflector). When you've got enough
sunlight to make it work, there's nothing silly about it - it saves
fuel and doesn't pollute the environment. That makes it poor measure
of silliness.

No, James, a /sunbeam/. When you (or the Galactic Patrol on your behalf)
concentrates the whole radiant output of the sun into a single beam.

I should have been a little more hintful.

--
'Don't be afraid: /Electra City/
there will be minimal destruction.' - Panic Room

Hewlett-Packard Limited registered office: Cain Road, Bracknell,
registered no: 690597 England Berks RG12 1HN
 
N

Nate Eldredge

Nick Keighley said:
I tried arguing once that FILE didn't have to be a struct. But one
of the Powers (I *think* Chris Torek) pointed out that it would be
difficult (I paraphrase) for it not to be a struct. He pointed
out that some of the low level calls (eg. getc) are required to be
implemented as both a macro and a function and (if I recall correctly)
the wording of The Standard almost forced it to be a struct.

I don't see what that would have to do with it. Even if getc has to be
implemented as a macro, there's no reason that macro can't *call* a
function.

int fgetc(FILE *f) { ... }
int getc(FILE *f) { return fgetc(f); }
#define getc(f) fgetc(f)

I can think of a couple ways to implement stdio where FILE is not a
struct, though granted they are a bit silly.

- On a POSIX-like system, FILE could be an int containing the file
descriptor. getc/putc call read() and write() with a single
character; no buffering is done. fflush() and setvbuf() are no-ops.

- FILE could itself be a pointer to the "real" file object, or an index
into an array of such objects.
 
P

Pawel Dziepak

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Eric said:
I'm not very familiar with the Windows API's, but it's my belief
that they use the term "handle" for various constructs that manage
files, processes, threads, and whatnot. Is Windows' "file handle"
the same thing as a FILE* or FILE, or does a FILE have a "file handle"
(or reference to same) buried somewhere within it? If the latter (and
again I confess unfamiliarity with the API's), then using the word
"handle" for two different things would be confusing, especially if
one sort of "handle" contains an instance of or reference to the other.

WinAPI has its own functions to manage files. However that's how MSDN
describes handles [1]:

"An application cannot directly access object data or the system
resource that an object represents. Instead, an application must obtain
an object handle, which it can use to examine or modify the system
resource. Each handle has an entry in an internally maintained table.
These entries contain the addresses of the resources and the means to
identify the resource type."

Which perfectly fits FILE definition with one exception, standard don't
mention that each FILE structure/whatever has an entry in an internal table.
However, we know that FILE consist of some kind of file descriptor (in
posix systems it will be just an integer) that is stored in an internal
table, that allows system to associate FILE with file on disk.
Concluding, FILE and handles seems to be very similar and that's why I
think that its not wrong to call FILE "a file handle". On the other
hand, it may be confusing, what that discussion showed very well.

[1] http://msdn.microsoft.com/en-us/library/ms724457.aspx

Pawel Dziepak
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org

iEYEARECAAYFAkkQgdcACgkQPFW+cUiIHNo26gCdGqlBD3r5KVFFDqfAm7aHkmEK
+zsAnik2/Loe1vvY1Sy14Wc8oDxtESLi
=J4aa
-----END PGP SIGNATURE-----
 
P

Pawel Dziepak

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Nate said:
I can think of a couple ways to implement stdio where FILE is not a
struct, though granted they are a bit silly.

- On a POSIX-like system, FILE could be an int containing the file
descriptor. getc/putc call read() and write() with a single
character; no buffering is done. fflush() and setvbuf() are no-ops.

- FILE could itself be a pointer to the "real" file object, or an index
into an array of such objects.

Ok, I didn't realize that situations. However, in that cases FILE is
some kind of pointer (maybe not exactly in the C standard meaning) to
structure.
That's why we can say that FILE is either a structure or a pointer to
structure.

Pawel Dziepak
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org

iEYEARECAAYFAkkQgusACgkQPFW+cUiIHNqgAACfQyZyUhyJBurrTPiAJC7o25Qf
QioAoI63HO8/ANJvbPYz9jRQusTNWx0e
=sd8S
-----END PGP SIGNATURE-----
 
K

Keith Thompson

Nate Eldredge said:
I can think of a couple ways to implement stdio where FILE is not a
struct, though granted they are a bit silly.

- On a POSIX-like system, FILE could be an int containing the file
descriptor. getc/putc call read() and write() with a single
character; no buffering is done. fflush() and setvbuf() are no-ops.

- FILE could itself be a pointer to the "real" file object, or an index
into an array of such objects.

FILE could be an array of unsigned char, with the standard functions
and macros converting between FILE* and, say, __HIDDEN_FILE* to access
the information. The point would be to make it just a little bit more
difficult to write code that depends on the internals of FILE.
 
B

Bill Cunningham

Standard C does not have file handles, or any other handles. If fopen
succeeds, it will return a FILE*. But not always. Even with w+,
fopen can fail and will return NULL.

I was just going to say in posix "b" has no meaning. But what about the
C standard? For maximal portability should a "b" be included in the code for
other systems like unixes and win32(64) ?

Bill
 
L

Lew Pitcher

I was just going to say in posix "b" has no meaning. But what about
the
C standard? For maximal portability should a "b" be included in the code
for other systems like unixes and win32(64) ?

Yes, for maximum portability, if your code expects a FILE * to carry binary
values, it should fopen() it with the "b" option. This ensures that, under
all platforms, the appropriate data interpretation/transformation takes
place. (Platforms that do not handle text differently from binary, such as
POSIX, Unix and Linux platforms, will do nothing special when you fopen()
with the "b" mode. However, platforms that *do* handle text different from
binary *will* properly handle non-textual data when you use the "b" mode.)


--
Lew Pitcher

Master Codewright & JOAT-in-training | Registered Linux User #112576
http://pitcher.digitalfreehold.ca/ | GPG public key available by request
---------- Slackware - Because I know what I'm doing. ------
 
C

CBFalconer

Nick said:
I tried arguing once that FILE didn't have to be a struct. But
one of the Powers (I *think* Chris Torek) pointed out that it
would be difficult (I paraphrase) for it not to be a struct. He
pointed out that some of the low level calls (eg. getc) are
required to be implemented as both a macro and a function and
(if I recall correctly) the wording of The Standard almost
forced it to be a struct.

No, getc is _permitted_ to be a macro, and even a macro that
evaluates its parameter more than once (thus making it unusable
with parameters having side effects). It may also be a function,
in which case it will be identical with fgetc. However a macro can
result in significant efficiency improvements for i/o, which is why
all this is allowed. The same applies to putc.

i.e. the following is NOT valid C code:

FILE *fa[COUNT]; /* array of FILE* pointers */
...
ch = getc(*fa++);
but
ch = getc(stdin);

is just fine.
 
M

Mark L Pappin

CBFalconer said:
No, getc is _permitted_ to be a macro, and even a macro that
evaluates its parameter more than once (thus making it unusable with
parameters having side effects). It may also be a function, in
which case it will be identical with fgetc. However a macro can
result in significant efficiency improvements for i/o, which is why
all this is allowed. The same applies to putc.

This permitted/required distinction seems to be overlooked by many
commentators. AIUI, getc() is also permitted to NOT be implemented as
a macro, i.e. a conforming implementation could have

#include <stdio.h>
int main(void) {
#ifdef getc
puts("yes");
#else
puts("no");
#endif
return 0;
}

produce "no" as output.

i.e. the following is NOT valid C code:

but not for any reason related to the preceding paragraph in your
post.
FILE *fa[COUNT]; /* array of FILE* pointers */
...
ch = getc(*fa++);

Incrementing an array, Chuck. Come on.

I think
FILE *fa[COUNT], **fpp = fa;
ch = getc(*fpp++);/* potential UB due to multi-eval of macro arg */
more closely illustrates the point I think you tried to make.
but
ch = getc(stdin);

is just fine.

Indeed.

mlp
 
C

Chris Dollin

Chris said:
No, James, a /sunbeam/. When you (or the Galactic Patrol on your behalf)
concentrates the whole radiant output of the sun into a single beam.

I should have been a little more hintful.

And that reply could have done with being a little more ... humble.
Sorry if I came over as being an ass; it's because I was being an ass.
 

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

fopen 20
fopen() questions 17
fopen 17
Problem with fopen 13
Working with files 1
HELP:function at c returning (null) 3
Python client/server that reads HTML body from server 1
URGENT 1

Members online

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,007
Latest member
obedient dusk

Latest Threads

Top