J
Jack Klein
Jack Klein said:
FLAME ON!!!
Oh. Was that it? Sheesh. Flame off again. (sigh)
This is pretty much how I do it, yes. Just a minor nit - FILE isn't (quite)
a perfect example, in at least two ways:
1) FILE should, in my opinion, be a truly opaque type, with the structure
definition hidden internally. typedef struct _iobuf FILE; is already more
than we need to know. The whole schmeer is far, far more than we need to
know.
I agree that FILE is not a perfectly opaque type, although I
deliberately decided not to complicate the point I was making to the
OP by bringing that up.
FILE cannot truly be an opaque type as far standard C is concerned for
the simple reason that the standard requires some functions to be
implemented as macros, and so some of the details must be exposed by
<stdio.h>.
Nevertheless, it is opaque enough for the point of the article, in the
sense that none of its internal details or workings are documented.
There is nothing that a strictly conforming program can do with a FILE
* other than through the documented functions.
2) I wish I wish I wish that fclose took FILE ** rather than FILE *, don't
you?
The one I consider much more important than that would be defining
fclose(NULL) as a no-op, just like free(NULL) is. It would greatly
simplify cleaning up resources. Right now you have to write code like
this:
WARNING: pseudo code not compiled, tested, or sanity checked!
return_type some_func( /*...*/)
{
FILE *fin = NULL;
FILE *fout = NULL;
data_type *data_ptr = NULL;
return_type something = DEFAULT_VALUE;
/* ... */
fin = fopen(...);
fout = fopen(...);
data_ptr = malloc(...);
/* ... */
if (fin) fclose(fin);
if (fout) fclose(fout);
free(data_type);
return something;
}
The additional checking for null FILE pointers before calling fclose()
is not a major effort, but it is just annoying enough to earn a place
on the pet peeve list after writing it INT_MAX times.
BTW, what's wrong with:
void rh_fclose(FILE **fp)
{
if (*fp)
{
fclose(*fp);
*fp = NULL;
}
}
Of course, I could just as easily write:
void jk_fclose(FILE *fp)
{
if (fp) fclose(fp);
}
Maybe time for both of us to make a new year's resolution to stop
carping about the easily fixable stuff?
Nah, that would take all the fun out of it!