In
any relationship it’s important to have boundaries that are respected by
all parties involved. When you create a library, you establish a relationship
with the
client
programmer
who uses that library to build an application or another library.
In
a C
struct,
as with most things in C, there are no rules. Client programmers can do
anything they want with that
struct,
and there’s no way to force any particular behaviors. For example, even
though you saw in the last chapter the importance of the functions named
initialize( )
and
cleanup( ),
the client programmer has the option not to call those functions. (We’ll
look at a better approach in the next chapter.) And even though you would
really prefer that the client programmer not directly manipulate some of the
members of your
struct,
in C there’s no way to prevent it. Everything’s naked to the world.
There
are two reasons for controlling access to
members. The first is to keep the client programmer’s hands off tools
they shouldn’t touch, tools that are necessary for the internal
machinations of the data type, but not part of the interface the client
programmer needs to solve their particular problems. This is actually a service
to client programmers because they can easily see what’s important to
them and what they can ignore.
The
second reason for access control is to allow the library designer to change the
internal workings of the structure without worrying about how it will affect
the client programmer. In the
Stack
example in the last chapter, you might want to allocate the storage in big
chunks, for speed, rather than creating new storage each time an element is
added. If the interface and implementation are clearly separated and protected,
you can accomplish this and require only a relink by the client programmer.