Re: Adding the ability to add functions into structures?



On Sat, 31 Dec 2005 05:54:27 +0000 (UTC), Richard Heathfield
<invalid@xxxxxxxxxxxxxxx> wrote in comp.lang.c:

> Jack Klein said:
>
> > I know I'll get flamed for this,
>
> FLAME ON!!!
>
> > but with the exception of inheritance
> > this is really nothing but syntactical sugar. You can write object
> > oriented programs in C right now.
>
> Oh. Was that it? Sheesh. Flame off again. (sigh)
>
> > A perfect example is the FILE data type, declared an <stdio.h>. It
> > has a creator, fopen(), a destructor, fclose(), and all sorts of
> > methods you can invoke on it via its pointer, such as fprintf(),
> > fscanf(), fread(), fwrite(), between its successful creation and its
> > destruction.
>
> 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!

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
.