1 /* Minimal object-oriented facilities for C.
2 Copyright (C) 2006, 2015 Free Software Foundation, Inc.
3 Written by Bruno Haible <bruno@clisp.org>, 2006.
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18 /* This file defines minimal facilities for object-oriented programming
21 The facilities allow to define classes with single inheritance and
24 Strict type checking is provided in combination with a C++ compiler:
25 The code compiles in ANSI C with less strict type checking; when
26 compiled with a C++ compiler, strict type checking is done.
28 In contrast to [OOC] and [OOPC], this implementation concentrates on the
29 bare essentials of an object-oriented programming style. It does not
30 provide features that are "sometimes useful", but not essential.
33 - Combination of fields and methods into a single object. YES
34 - Description of objects of same shape and same behaviour
36 - Single inheritance. YES
37 - Multiple inheritance. NO
38 - Operator overloading (compile-time polymorphism). NO
39 - Virtual methods (run-time polymorphism). YES
40 - Information hiding: private/protected/public. private fields
41 - Static fields and methods. NO
42 - Constructors, destructors. NO
44 - Exception handling. NO
45 - Garbage collection. NO
46 - Templates / Generic classes with parameters. NO
48 - Hidden 'this' pointer in methods. NO
49 - Declaring or implementing several classes in the same file. NO
52 - Multiple inheritance is not supported because programming languages
53 like Java and C# prove that they are not necessary. Modern design
54 patterns use delegation more often than composition; this reduces
55 the pressure to use multiple inheritance.
56 Multiple inheritance of "interfaces" (classes without fields) might
57 be considered, though.
58 - Operator overloading is not essential: The programmer can rename
59 methods so that they carry unambiguous method names. This also makes
60 the code more readable.
61 - Virtual methods are supported. Non-virtual methods are not: they
62 constitute an assumption about the possible subclasses which is more
63 often wrong than right. In other words, non-virtual methods are a
64 premature optimization - "the root of all evil", according to
66 - Information hiding: 'protected' is not supported because it is always
67 inappropriate: it prohibits the use of the delegation design pattern.
68 'private' is implemented on fields. There are no 'public' fields,
69 since the use of getters/setters allows for overriding in subclasses
70 and is more maintainable (ability to set breakpoints). On the other
71 hand, all methods are 'public'. 'private` methods are not supported
72 because methods with static linkage can be used instead.
73 - Static fields and methods are not supported because normal variables
74 and functions with static or extern linkage can be used instead.
75 - Constructors and destructors are not supported. The programmer can
76 define 'init' and 'do_free' methods himself.
77 - 'new', 'delete' are not supported because they only provide the
78 grouping of two lines of code into a single line of code.
79 - Exception handling is not supported because conventions with a return
80 code can be used instead.
81 - Garbage collection is not supported. Without it the programmer's life
82 is harder, but not impossible. The programmer has to think about
84 - Templates / Generic classes with parameters are not supported because
85 they are mostly used for container classes, and container classes can
86 be implemented in a simpler object-oriented way that requires only a
87 very limited form of class inheritance.
88 - Namespaces are not implemented, because they can be simulated by a
89 consistent naming convention.
90 - A hidden 'this' pointer in methods is not implemented. It reduces the
91 transparency of the code (because what looks like a variable access can
92 be an access through 'this') and is simply not needed.
93 - Declaring or implementing several classes in the same file is not
94 supported, because it is anyway good practice to define each class in
95 its own .oo.h / .oo.c file.
99 The syntax resembles C++, but deviates from C++ where the C++ syntax is
102 A root class is declared in a .oo.h file:
107 int method1 (rootfoo_t x, ...); ...
110 and in the corresponding .oo.c file:
118 A subclass is declared in a .oo.h file as well:
120 struct subclass : struct rootfoo
123 int method2 (subclass_t x, ...); ...
126 and in the corresponding .oo.c file:
128 struct subclass : struct rootfoo
135 - An incomplete type 'struct any_rootfoo_representation' or
136 'struct subclass_representation', respectively. It denotes the memory
137 occupied by an object of the respective class. The prefix 'any_' is
138 present only for a root class.
139 - A type 'rootfoo_t' or 'subclass_t' that is equivalent to a pointer
140 'struct any_rootfoo_representation *' or
141 'struct subclass_representation *', respectively.
142 - A type 'struct rootfoo_implementation' or
143 'struct subclass_implementation', respectively. It contains a virtual
144 function table for the corresponding type.
145 - A type 'struct rootfoo_representation_header' or
146 'struct subclass_representation_header', respectively, that defines
147 the part of the memory representation containing the virtual function
149 - Functions 'rootfoo_method1 (rootfoo_t x, ...);' ...
150 'subclass_method1 (subclass_t x, ...);' ...
151 'subclass_method2 (subclass_t x, ...);' ...
152 that invoke the corresponding methods. They are realized as inline
153 functions if possible.
154 - A declaration of 'rootfoo_typeinfo' or 'subclass_typeinfo', respectively,
155 each being a typeinfo_t instance.
156 - A declaration of 'ROOTFOO_SUPERCLASSES' or 'SUBCLASS_SUPERCLASSES',
157 respectively, each being an initializer for an array of typeinfo_t.
158 - A declaration of 'ROOTFOO_SUPERCLASSES_LENGTH' or
159 'SUBCLASS_SUPERCLASSES_LENGTH', respectively, each denoting the length
161 - A declaration of 'rootfoo_vtable' or 'subclass_vtable', respectively,
162 being an instance of 'struct rootfoo_implementation' or
163 'struct subclass_implementation', respectively.
164 - A header file "rootfoo.priv.h" or "subclass.priv.h" that defines the
165 private fields of 'struct rootfoo_representation' or
166 'struct subclass_representation', respectively.
168 A class implementation looks like this, in a .oo.c file:
170 struct subclass : struct rootfoo
176 int subclass::method1 (subclass_t x, ...) { ... } [optional]
177 int subclass::method2 (subclass_t x, ...) { ... }
180 At the place of the second "struct subclass" definition, the type
181 'struct subclass_representation' is expanded, and the macro 'super' is
182 defined, referring to the vtable of the superclass. For root classes,
183 'super' is not defined. Also, 'subclass_typeinfo' is defined.
185 Each method subclass::method_i defines the implementation of a method
186 for the particular class. Its C name is subclass__method_i (not to be
187 confused with subclass_method_i, which is the externally visible function
188 that invokes this method).
190 Methods that are not defined implicitly inherited from the superclass.
192 At the end of the file, 'subclass_vtable' is defined, as well as
193 'subclass_method1 (subclass_t x, ...);' ...
194 'subclass_method2 (subclass_t x, ...);' ...
195 if they were not already defined as inline functions in the header file.
197 Object representation in memory:
198 - Objects have as their first field, called 'vtable', a pointer to a table
199 to data and function pointers that depend only on the class, not on the
201 - One of the first fields of the vtable is a pointer to the
202 'superclasses'; this is a NULL-terminated array of pointers to
203 typeinfo_t objects, starting with the class itself, then its
207 [OOC] Axel-Tobias Schreiner: Object-oriented programming with ANSI-C. 1993.
209 [OOPC] Laurent Deniau: Object Oriented Programming in C. 2001.
216 /* Get size_t, abort(). */
219 /* An object of this type is defined for each class. */
222 const char *classname;
225 /* IS_INSTANCE (OBJ, ROOTCLASSNAME, CLASSNAME)
226 tests whether an object is instance of a given class, given as lower case
228 #define IS_INSTANCE(obj,rootclassname,classname) \
229 (((const struct rootclassname##_representation_header *)(const struct any_##rootclassname##_representation *)(obj))->vtable->superclasses_length \
230 >= classname##_SUPERCLASSES_LENGTH \
231 && ((const struct rootclassname##_representation_header *)(const struct any_##rootclassname##_representation *)(obj))->vtable->superclasses \
232 [((const struct rootclassname##_representation_header *)(const struct any_##rootclassname##_representation *)(obj))->vtable->superclasses_length \
233 - classname##_SUPERCLASSES_LENGTH] \
234 == & classname##_typeinfo)
235 /* This instance test consists of two comparisons. One could even optimize
236 this to a single comparison, by limiting the inheritance depth to a fixed
237 limit, for example, say, depth <= 10. The superclasses list would then
238 need to be stored in reverse order, from the root down to the class itself,
239 and be filled up with NULLs so that the array has length 10. The instance
240 test would look like this:
241 #define IS_INSTANCE(obj,rootclassname,classname) \
242 (((const struct rootclassname##_representation_header *)(const struct any_##rootclassname##_representation *)(obj))->vtable->superclasses \
243 [classname##_SUPERCLASSES_LENGTH - 1] \
244 == & classname##_typeinfo)
245 but the classname##_superclasses_length would no longer be available as a
246 simple sizeof expression. */