Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!usc!chaph.usc.edu!alcor.usc.edu!jeenglis From: jeenglis@alcor.usc.edu (Joe English) Newsgroups: comp.lang.c Subject: Re: Info Hiding in C Keywords: Hiding Message-ID: <16645@chaph.usc.edu> Date: 17 Apr 91 05:54:37 GMT References: <1991Apr17.004044.22940@ux1.cso.uiuc.edu> Sender: news@chaph.usc.edu Organization: A child, an elderly man, a Cuban Lines: 80 Nntp-Posting-Host: alcor.usc.edu unicorn@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@alcor.usc.edu