Originally published by Robert Beisert at fortcollinsprogram.robert-beisert.com

Patterns: “Classes” in C

Encapsulation is a key aspect of the Object Oriented Programming model, and for good reason. We have an easier time grasping units which do one thing than hundreds of independent operations and objects that can do a number of things. While C does not contain the “class” descriptor found in C++ or Java, we can accomplish a similar task with naming conventions.

Principles of Classes

Before we consider a structure for naming classes, we have to consider the meaning of “class”.

The highest-level observation about classes is that they act as a unit. Specifically, a class consists of a structure and a set of functions that operate on that structure. Of course, the structure is the key root of the class, because all the functions address that structure in one way or another.

Second, we can observe that classes in Java are relegated to their OWN separate code files. This is due to a shortcut by the Java developers (who decided it was easier to prevent collisions by relegating classes to specifically named files), but it is applicable to all coding conventions. In compliance with the unitary nature of classes, it makes sense to keep all the functionality required for a class in a single file.

Finally, we observe that each class has its own functions (or “methods”) that work explicitly on that class object. These methods may not have globally unique names in the source code (which is a cause for complaint by those of us who employ Linux utilities to accelerate our programming), but the symbol table produced always contains globally unique names by prepending a host of unique identifying values, which may include class name, namespace, and (potentially) file name from which the function is derived.

These observations allow us to construct classes in C, only with much simpler dynamics.

Naming Convention

Let’s approach the naming convention using the pattern of our observations.

First, we note that classes are built around a structure. This structure should have a unique name (because all names in C must be unique). Furthermore, all functions which we would call “class methods” in an OOP language should be visually tied to that structure.

First: All functions related to a structure (“class”) must contain the name of that structure.

Second, we note that all classes in Java are relegated to a single file. This is a reasonable practice.

Second: All class structures and functions must be contained in the same file.

Third, we observe that each symbol produced by the OOP compilers and interpreters is globally unique, regardless of the original name’s uniqueness. We can apply that to our code by prepending an aspect of the file name directly to everything related to the class.

Third: All class structures and functions must begin with the name of the file in which they are contained (or a logical subset thereof, which is known to all users).

 

This results in a naming convention that looks something like this:

FileName_Structure

FileName_Structure_Function

If you code using typedef-ed pointers (which is useful for creating “private” data elements – you conceal the structures by omitting them from the .h file, restricting access only to defined accessor functions), you can use a format like this to immediately differentiate between pointers and structures:

typedef struct FileName_Structure FILENAME_STRUCTURE

Finally, if you’re concerned about confusing variables which are passed-in with those employed or created internally, you can designate a naming convention like this to keep them safe:

function_variable

 

Lesson: We can use naming conventions to logically group functions and structures, establishing meaningful names while preserving global uniqueness.

photo by: