Info Hiding in C

Joe English jeenglis at alcor.usc.edu
Wed Apr 17 15:54:37 AEST 1991


unicorn at uxh.cso.uiuc.edu (Harry E Miller) writes:

>I wish to include optional information hiding within this library,
>so that the programer can only get string information from a
>function (not a macro!).
> [...]
>Also why won't this work?
>
>typedef void String[6];

It's not allowed.  Why?  Basically, because it doesn't
make sense.  'void' means, informally, 'no value'; you're
trying to declare an array of six nothings.

Anyway, on to this:

>#ifdef INFO_HIDING
>[...]
>typedef char String[6];   /* Hidden string */
>#else
>typedef struct _string {  /* 0x00 | string structure               */
>        char *str;        /* 0x02 | pointer to the char array      */
>        unsigned length;  /* 0x04 | current length of str          */
>        unsigned alloc;   /* 0x06 | amount allocated to str        */
>} _String;                /* 0x07 | end of _string structure       */
>typedef _String String;
>#endif

First of all, a 'struct _string' is not necessarily six
bytes long, even when sizeof(char *) = sizeof(unsigned) = 2.
It may happen to be six bytes long under the current version
of your particular compiler in that particular memory model,
but that won't always be the case.   (You said you were using
Turbo C on a PC, right?  Try, I think, 'tcc -mc' instead of
plain 'tcc'.  The code won't work anymore.)  A better way
to do this is to use:

struct _string {
    ...     /* same as above */
};

typedef char String[sizeof(struct _string)];

and it will work on any platform/compiler/memory model.

The rest looks basically OK.  In my opinion it's overkill,
though;  here's how I usually do information hiding in C:

typedef struct Foo {
    /* PUBLIC: */
    ... publically usable members go here ...
    /* READONLY: */
    ... publically readable members go here ...
    /* PRIVATE: */
    ... private stuff goes here ...
} Foo;

... prototypes for functions manipulating Foos go here ...

That's all the information hiding I need.  Namespace clutter
isn't any more of a problem than it is in C++, since all
of struct Foo's member names are in their own namespace.
True, the compiler won't generate an error if I try to access
or write to the wrong members, but then again it doesn't issue
a warning when I futz around with the contents of a FILE * 
either, but I use stdio all the time without any loss of
data abstraction.  The words "PRIVATE" and "READONLY" in large
friendly letters are sufficient to let me and anyone else
who reads the .h file know that certain members are none
of my business.  I don't find it productive to play tricks
with the compiler to keep me from shooting myself in the foot.

(NB: For *complete* information hiding, there shouldn't really
be a "READONLY" section.  I use it a lot myself, but I'm starting
to wonder if it's a bad habit...)


--Joe English

  jeenglis at alcor.usc.edu



More information about the Comp.lang.c mailing list