You are here: Home » c programming » How To Hide A Struct Member in the C Programming Language

How To Hide A Struct Member in the C Programming Language

by David M. Doolin, PhD on June 1, 2009

Update: A friend pointed out a typo, which is now fixed in both the article and the code.


Hiding a struct member in C is easy using incomplete types. There’s two ways to do it:

  1. Hide the whole struct definition
  2. Hide a single member of a struct

Either way requires using a typedef to define an incomplete type, where the definition of the type is separate from the declaration of the type.

If you do any coding in the C programming language at all, learning this simple technique will provide you with many benefits:

  1. Your programs will become cleaner as you learn the techniques of encapsulation and data hiding
  2. You will find other C source code easier to read
  3. Lastly, you will much better understand how object-oriented languages such as Java work.
WARNING: Extensively employing incomplete types requires that you adopt bulletproof memory management strategies.

Method 1: Hide the whole struct

Hiding the whole struct is enabled declaring a typedef in a header file and defining the struct in the source file. Here’s the source for foo.h (download).

1
2
3
4
5
6
#ifndef IS_FOO_H
#define IS_FOO_H
 
typedef struct _foo Foo;
 
#endif /* IS_FOO_H */

We define the struct in foo.c:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio .h>
#include "foo.h"
 
struct _foo {
  int bar;
  int baz;
};
 
int 
main(int argc, char ** argv) {
 
  Foo foo;
  foo.bar = 1;
  foo.baz = 2;
  fprintf(stdout,"Foo.bar: %d, Foo.baz: %dn",foo.bar, foo.baz);
 
  return 0;
}
</stdio>

The key is using the typedef in a header file.

Method 2: Hide one member of a struct

The second method uses a technique called aggregation, where one type is defined as a collection of other types or data. A struct or a relational database table aggregates types or data. Continuing from above, let’s add a pointer to Foo type to a new struct called Snafu:

1
2
3
4
struct _snafu  {
   Foo * f;
   int fubar;
};

Now we all the members of Foo hidden from all users of Snafu. We can’t really do anything with it, since there isn’t any memory allocation code written for Foo. If there were allocation code, the f could be set to a pointer value.

Simple inheritance

Just to be complete, Foo could be added like this, provided the definition of Foo was in scope (which it isn’t in this example):

1
2
3
4
struct _snafu {
   Foo f;
   int fubar;
};

Notice something else: because we declared Foo in the first position of Snafu, we could treat Snafu as a child class of Foo, such the Snafu inherits from Foo. But we’re not going to, we’ll deal with classes in a future article on object-oriented C programming. Choosing whether to declare the struct variable in whole or referencing it using a pointer depends on the purpose of the code, specifically, when, where and how the memory for Foo is going to handled. Memory handling is definitely going off the deep end for this article.

Incomplete types are powerful tools

In C, using incomplete types is necessary to encapsulate data necessary for one subsystem from being referenced by another. It’s possible to use this technique as part of a method for constructing object-oriented systems in pure C, including systems using “protected” classes where the struct internals are defined in a private header file thats used within the object system.

Don’t forget to download the source code!

>>>NOTE: Here’s much longer article which goes into more detail on incomplete and derived types.

Share and Enjoy:
  • Digg
  • StumbleUpon
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • TwitThis

{ 1 trackback }

Data Hiding in C Programming Using Incomplete and Derived Types | There Is NO Box
June 1, 2009 at 1:26 pm

{ 2 comments… read them below or add one }

Richard Hagberg December 17, 2009 at 2:53 pm

I tried this in the IAR compiler, and It kept giving me an error about incomplete data types. I was just wondering what compiler you were using.

Reply

Dave Doolin | Website In A Weekend December 17, 2009 at 4:30 pm

At some point before you use or dereference the struct you have to define it, and that’s most likely what’s at issue.
Dave Doolin | Website In A Weekend´s last blog ..Dynamic Content Generation – How WordPress is Like a Sushi Restaurant My ComLuv Profile

Reply

Leave a Comment

CommentLuv Enabled