chiark / gitweb /
Fix spelling of `Sensible' in all of the header comments.
[sod] / lib / sod-structs.3
CommitLineData
47de28ae
MW
1.\" -*-nroff-*-
2.\"
3.\" Description of the main Sod data structures
4.\"
5.\" (c) 2015 Straylight/Edgeware
6.\"
7.
8.\"----- Licensing notice ---------------------------------------------------
9.\"
e0808c47 10.\" This file is part of the Sensible Object Design, an object system for C.
47de28ae
MW
11.\"
12.\" SOD is free software; you can redistribute it and/or modify
13.\" it under the terms of the GNU General Public License as published by
14.\" the Free Software Foundation; either version 2 of the License, or
15.\" (at your option) any later version.
16.\"
17.\" SOD is distributed in the hope that it will be useful,
18.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
19.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20.\" GNU General Public License for more details.
21.\"
22.\" You should have received a copy of the GNU General Public License
23.\" along with SOD; if not, write to the Free Software Foundation,
24.\" Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25.
9ed8eb2a 26.\" Highlight using terminal escapes, rather than overstriking.
47de28ae 27.\"\X'tty: sgr 1'
9ed8eb2a 28.
47de28ae
MW
29.\" String definitions and font selection.
30.ie t \{\
31. ds o \(bu
32. if \n(.g .fam P
33.\}
34.el \{\
35. ds o o
36.\}
37.
38.\" .hP TEXT -- start an indented paragraph with TEXT hanging off to the left
39.de hP
40.IP
41\h'-\w'\fB\\$1\ \fP'u'\fB\\$1\ \fP\c
42..
43.
44.\"--------------------------------------------------------------------------
45.TH sod-structs 3 "8 September 2015" "Straylight/Edgeware" "Sensible Object Design"
46.
47.SH NAME
48sod-structs \- main Sod data structures
49.
50.\"--------------------------------------------------------------------------
51.SH SYNOPSIS
52.nf
53.ft B
54#include <sod/sod.h>
55
56typedef struct SodObject__ichain_obj SodObject;
57typedef struct SodClass__ichain_obj SodClass;
58
59struct sod_instance {
60\h'2n'const struct sod_vtable *_vt;
61};
62
63struct sod_vtable {
64\h'2n'const SodClass *_class;
65\h'2n'size_t _base;
66};
67
68struct SodObject__vt_obj {
69\h'2n'const SodClass *_class;
70\h'2n'size_t _base;
71};
72
73struct SodObject__ilayout {
74\h'2n'union {
75\h'4n'struct SodObject__ichain_obj {
76\h'6n'const struct SodObject__vt_obj *_vt;
77\h'4n'};
78\h'2n'} obj;
79};
80
81extern const struct SodClass__ilayout SodObject__classobj;
82#define SodObject__class (&SodObject__classobj.obj.cls)
83
84struct SodClass__vt_obj {
85\h'2n'const SodClass *_class;
86\h'2n'size_t _base;
87};
88
89struct SodObject__ilayout {
90\h'2n'union {
91\h'4n'struct SodClass__ichain_obj {
92\h'6n'const struct SodClass__vt_obj *_vt;
93\h'6n'struct SodClass__islots {
94\h'8n'const char *name;
95\h'8n'const char *nick;
96\h'8n'size_t initsz;
97\h'8n'void *(*imprint)(void *\fIp\fB);
98\h'8n'void *(*init)(void *\fIp\fB);
99\h'8n'size_t n_supers;
100\h'8n'const SodClass *const *supers;
101\h'8n'size_t n_cpl;
102\h'8n'const SodClass *const *cpl;
103\h'8n'const SodClass *link;
104\h'8n'const SodClass *head;
105\h'8n'size_t level;
106\h'8n'size_t n_chains;
107\h'8n'const struct sod_chain *chains;
108\h'8n'size_t off_islots;
109\h'8n'size_t islotsz;
110\h'6n'} cls;
111\h'4n'};
112\h'4n'SodObject obj;
113\h'2n'} obj;
114};
115
116struct sod_chain {
117\h'2n'size_t n_classes;
118\h'2n'const SodClass *const *classes;
119\h'2n'size_t off_ichain;
120\h'2n'const struct sod_vtable *vt;
121\h'2n'size_t ichainsz;
122};
123
124extern const struct SodClass__ilayout SodClass__classobj;
125#define SodClass__class (&SodClass__classobj.obj.cls)
126.fi
127.ft P
128.
129.\"--------------------------------------------------------------------------
130.SH DESCRIPTION
131.
132This page describes the structure and layout
133of standard Sod objects, classes and associated metadata.
134Note that Sod's object system is very flexible
135and it's possible for an extension
136to define a new root class
137which works very differently from the standard
138.B SodObject
139described here.
140.
141.\"--------------------------------------------------------------------------
142.SH COMMON INSTANCE STRUCTURE
143.
144As described below,
145a pointer to an instance actually points to an
146.I "instance chain"
147structure within the instances overall layout structure.
148.PP
149Instance chains contain slots and vtable pointers,
150as described below.
151All instances have the basic structure of a
152.BR "struct sod_instance" ,
153which has the following members.
154.TP
155.B "const struct sod_vtable *_vt"
156A pointer to a
157.IR vtable ,
158which has the basic structure of a
159.BR "struct sod_vtable" ,
160described below.
161.PP
162A vtable contains static metadata needed
163for efficient conversions and
164message dispatch,
165and pointers to the instance's class.
166Each chain points to a different vtable
167All vtables have the basic structure of a
168.BR "struct sod_vtable" ,
169which has the following members.
170.TP
171.B "const SodClass *_class"
172A pointer to the instance's class object.
173.TP
174.B "size_t _base;"
175The offset of this chain structure
176above the start of the overall instance layout, in bytes.
177Subtracting
178.B _base
179from the instance chain pointer
180finds the layout base address.
181.
182.\"--------------------------------------------------------------------------
183.SH BUILT-IN ROOT OBJECTS
184.
185This section describes the built-in classes
186.B SodObject
187and
188.BR SodClass ,
189which are the standard roots of the inheritance and metaclass graphs
190respectively.
191Specifically,
192.B SodObject
193has no direct superclasses,
194and
195.B SodClass
196is its own metaclass.
9c4a4110
MW
197It is not possible to define root classes in module files
198because of circularities:
47de28ae
MW
199.B SodObject
200has
201.B SodClass
9c4a4110
MW
202as its metaclass,
203and
47de28ae
MW
204.B SodClass
205is a subclass of
206.BR SodObject .
207Extensions can define additional root classes,
208but this is tricky,
209and not really to be recommended.
210.
211.SS The SodObject class
212The
213.B SodObject
214class defines no slots or messages.
215Because
216.B SodObject
217has no direct superclasses,
218there is only one chain,
219and no inherited slots or messages,
220so the single chain contains only a vtable pointer.
221.PP
222Since there are no messages,
223and
224.B SodClass
225also has only one chain,
226the vtable contains only the standard class pointer and offset-to-base
227members.
228In an actual instance of
229.B SodObject
230(why would you want one?)
231the class pointer contains the address of
232.B SodObject__class
233and the offset is zero.
234.
235.SS The SodClass class
236The
237.B SodClass
238class defines no messages,
239but there are a number of slots.
240Its only direct superclass is
241.B SodObject
242and so (like its superclass) its vtable is trivial.
243.PP
244The slots defined are as follows.
245.TP
246.B const char *name;
247A pointer to the class's name.
248.TP
249.B const char *nick;
250A pointer to the class's nickname.
251.TP
252.B size_t initsz;
253The size in bytes required to store an instance of the class.
254.TP
255.BI "void *(*imprint)(void *" p );
256A pointer to a function:
257given a pointer
258.I p
259to at least
260.I initsz
261bytes of appropriately aligned memory,
262`imprint' this memory it so that it becomes a minimally functional
263instance of the class:
264all of the vtable and class pointers are properly initialized,
265but the slots are left untouched.
266The function returns its argument
267.IR p .
268.TP
269.BI "void *(*init)(void *" p );
270A pointer to a function:
271given a pointer
272.I p
273to at least
274.I initsz
275bytes of appropriately aligned memory,
276initialize an instance of the class in it:
277all of the vtable and class pointers are initialized,
278as are slots for which initializers are defined.
279Other slots are left untouched.
280The function returns its argument
281.IR p .
282.TP
283.B size_t n_supers;
284The number of direct superclasses.
285(This is zero exactly in the case of
286.BR SodObject .)
287.TP
288.B const SodClass *const *supers;
289A pointer to an array of
290.I n_supers
291pointers to class objects
292listing the class's direct superclasses,
293in the order in which they were listed in the class definition.
294If
295.I n_supers
296is zero,
297then this pointer is null.
298.TP
299.B size_t n_cpl;
300The number of superclasses in the class's class precedence list.
301.TP
302.B const SodClass *const *cpl;
303A pointer to an array of pointers to class objects
304listing all of the class's superclasses,
305from most- to least-specific,
306starting with the class itself,
307so
308.IB c ->cls.cpl[0]
309=
310.I c
311for all class objects
312.IR c .
313.TP
314.B const SodClass *link;
315If the class is a chain head, then this is a null pointer;
316otherwise it points to the class's distinguished link superclass
317(which might or might not be a direct superclass).
318.TP
319.B const SodClass *head;
320A pointer to the least-specific class in this class's chain;
321so
322.IB c ->cls.head->cls.link
323is always null,
324and either
325.IB c ->cls.link
326is null
327(in which case
328.IB c ->cls.head
329=
330.IR c )
331or
332.IB c ->cls.head
333=
334.IB c ->cls.link->cls.head \fR.
335.TP
336.B size_t level;
337The number of less specific superclasses in this class's chain.
338If
339.IB c ->cls.link
340is null then
341.IB c ->cls.level
342is zero;
343otherwise
344.IB c ->cls.level
345=
346.IB c ->cls.link->cls.level
347+ 1.
348.TP
349.B size_t n_chains;
350The number of chains formed by the class's superclasses.
351.TP
352.B const struct sod_chain *chains;
353A pointer to an array of
354.B struct sod_chain
355structures (see below) describing the class's superclass chains,
356in decreasing order of specificity of their most specific classes.
357It is always the case that
358.IB c ->cls.chains[0].classes[ c ->cls.level]
359=
360.IR c .
361.TP
362.B size_t off_islots;
363The offset of the class's
364.B islots
365structure relative to its containing
366.B ichain
367structure.
368The class doesn't define any slots if and only if this is zero.
369(The offset can't be zero because the vtable pointer is at offset zero.)
370.TP
371.B size_t islotsz;
372The size required to store the class's direct slots,
373i.e., the size of its
374.B islots
375structure.
376The class doesn't define any slots if and only if this is zero.
377.PP
378The
379.B struct sod_chain
380structure describes an individual chain of superclasses.
381It has the following members.
382.TP
383.B size_t n_classes;
384The number of classes in the chain.
385This is always at least one.
386.TP
387.B const SodClass *const *classes;
388A pointer to an array of class pointers
389listing the classes in the chain from least- to most-specific.
390So
391.IB classes [ i ]->cls.head
392=
393.IB classes [0]
394for all
3950 \(<=
396.I i
397<
398.IR n_classes ,
399.IB classes [0]->cls.link
400is always null,
401and
402.IB classes [ i ]->cls.link
403=
404.IB classes [ "i\fR \- 1" ]
405if
4061 \(<=
407.I i
408<
409.IR n_classes .
410.TP
411.B size_t off_ichain;
412The size of the
413.B ichain
414structure for this chain.
415.TP
416.B const struct sod_vtable *vt;
417The vtable for this chain.
418(It is possible, therefore, to duplicate the behaviour of the
419.I imprint
420function by walking the chain structure.
421The
422.I imprint
423function is much faster, though.)
424.TP
425.B size_t ichainsz;
426The size of the
427.B ichain
428structure for this chain.
429.
430.\"--------------------------------------------------------------------------
431.SH CLASS AND VTABLE LAYOUT
432.
433The layout algorithms for Sod instances and vtables are nontrivial.
434They are defined here in full detail,
435since they're effectively fixed by Sod's ABI compatibility guarantees,
436so they might as well be documented for the sake of interoperating
437programs.
438.PP
439Unfortunately, the descriptions are rather complicated,
440and, for the most part not necessary to a working understanding of Sod.
441The skeleton structure definitions shown should be more than enough
442for readers attempting to make sense of the generated headers and tables.
443.PP
444In the description that follows,
445uppercase letters vary over class names,
446while the corresponding lowercase letters indicate the class nicknames.
447Throughout, we consider a class
448.I C
449(therefore with nickname
450.IR c ).
451.
452.SS Generic instance structure
453The entire state of an instance of
454.I C
455is contained in a single structure of type
456.B struct
457.IB C __ilayout \fR.
458.IP
459.nf
460.ft B
461struct \fIC\fB__ilayout {
462\h'2n'union \fIC\fB__ichainu_\fIh\fB {
463\h'4n'struct \fIC\fB__ichain_\fIh\fB {
464\h'6n'const struct \fIC\fB__vt_\fIh\fB *_vt;
465\h'6n'struct \fIH\fB__islots \fIh\fB;
466\h'6n'\fR...\fB
467\h'6n'struct \fIC\fB__islots {
468\h'8n'\fItype\fB \fIslota\fB;
469\h'8n'\fR...\fB
470\h'6n'} \fIc\fB;
471\h'4n'} \fIc\fB;
472\h'4n'\fR...\fB
473\h'4n'struct \fIH\fB__ichain_\fIh\fB \fIh\fB;
474\h'2n'} \fIh\fB;
475\h'2n'union \fIB\fB__ichainu_\fIi\fB \fIi\fB;
476\h'2n'\fR...\fB
477};
478
479typedef struct \fIC\fB__ichain_\fIh\fB \fIC\fB;
480.ft P
481.fi
482.PP
483The set of superclasses of
484.IR C ,
485including itself,
486can be partitioned into chains
487by following their distinguished superclass links.
488(Formally, the chains are the equivalence classes determined by
489the reflexive, symmetric, transitive closure of
490the `links to' relation.)
491Chains are identified by naming their least specific classes;
492the least specific class in a chain is called the
493.IR "chain head" .
494Suppose that the chain head of the chain containing
495.I C
496itself is named
497.I H
498(though keep in mind that it's possible that
499.I H
500is in fact
501.I C
502itself.)
503.PP
504The
505.B ilayout
506structure contains one member for each of
507.IR C 's
508superclass chains.
509The first such member is
510.IP
511.B
512.B union
513.IB C __ichainu_ h
514.IB h ;
515.PP
516described below;
517this is followed by members
518.IP
519.B union
520.IB B __ichainu_ i
521.IB i ;
522.PP
523for each other chain,
524where
525.I I
526is the head
527and
528.I B
529the tail (most-specific) class of the chain.
530The members are in decreasing order
531of the specificity of the chains' most-specific classes.
532(Note that all but the first of these unions
533has already been defined as part of
534the definition of the corresponding
535.IR B .)
536.PP
537The
538.B ichainu
539union contains a member for each class in the chain.
540The first is
541.IP
542.B struct
543.IB C __ichain_ h
544.IB c ;
545.PP
546and this is followed by corresponding members
547.IP
548.B struct
549.IB A __ichain_ h
550.IB a ;
551.PP
552for each of
9c4a4110
MW
553.IR C 's
554superclasses
47de28ae
MW
555.IR A
556in the same chain in some (unimportant) order.
557A `pointer to
558.IR C '
559is always assumed
560(and, indeed, defined in C's type system)
561to be a pointer to the
562.B struct
563.IB C __ichain_ h \fR.
564.PP
565The
566.B ichain
567structure contains (in order), a pointer
568.IP
569.B const
570.B struct
571.IB C __vt_ h
572.B *_vt;
573.PP
574followed by a structure
575.IP
576.B struct
577.IB A __islots
578.IB a ;
579.PP
580for each superclass
581.I A
582of
583.IR C
584in the same chain which defines slots,
585from least- to most-specific;
586if
587.I C
588defines any slots,
589then the last member is
590.IP
591.B struct
592.IB C __islots
593.IB c ;
594.PP
595Finally, the
596.B islots
597structure simply contains one member for each slot defined by
598.I C
599in the order they appear in the class definition.
600.
601.SS Generic vtable structure
602As described above,
603each
604.B ichain
605structure of an instance's storage
606has a vtable pointer
607.IP
608.B const
609.B struct
610.IB C __vt_ h
611.B *_vt;
612.PP
613In general,
614the vtables for the different chains
615will have
616.I different
617structures.
618.PP
619The instance layout split neatly into disjoint chains.
620This is necessary because
621each
622.B ichain
623must have as a prefix the
624.B ichain
9c4a4110
MW
625for each superclass in the same chain,
626and each slot must be stored in exactly one place.
47de28ae
MW
627The layout of vtables doesn't have this second requirement:
628it doesn't matter that there are
629multiple method entry pointers
630for the same effective method
631as long as they all work correctly.
9c4a4110
MW
632Indeed, it's essential that they do,
633because each chain's method entry function
634will need to apply a different offset to the receiver pointer
635before invoking the effective method.
47de28ae
MW
636.PP
637A vtable for a class
638.I C
639with chain head
640.I H
641has the following general structure.
642.IP
643.nf
644.ft B
645union \fIC\fB__vtu_\fIh\fB {
646\h'2n'struct \fIC\fB__vt_\fIh\fB {
647\h'4n'const \fIP\fB *_class;
648\h'4n'size_t _base;
649\h'4n'\fR...\fB
650\h'4n'const \fIQ\fB *_cls_\fIj\fB;
651\h'4n'\fR...\fB
652\h'4n'ptrdiff_t _off_\fIi\fB;
653\h'4n'\fR...\fB
654\h'4n'struct \fIC\fB__vtmsgs_\fIa\fB {
655\h'6n'\fItype\fB (*\fImsg\fB)(\fIC\fB *, \fR...\fB);
656\h'6n'\fR...\fB
657\h'4n'} \fIa\fB;
658\h'4n'\fR...\fB
659\h'2n'} \fIc\fB;
660};
661
662extern const union \fIC\fB__vtu_\fIh\fB \fIC\fB__vtable_\fIh\fB;
663.ft P
664.fi
665.PP
666The outer layer is a
47de28ae
MW
667.B union
668.IB C __vtu_ h
47de28ae
MW
669containing a member
670.IP
671.B struct
672.IB A __vt_ h
673.IB a ;
674.PP
675for each of
676.IR C 's
677superclasses
678.I A
679in the same chain,
680with
681.I C
682itself listed first.
683This is mostly an irrelevant detail,
684whose purpose is to defend against malicious compilers:
685pointers are always to one of the inner
686.B vt
687structures.
688It's important only because it's the outer
689.B vtu
690union which is exported by name.
691Specifically, for each chain of
692.IR C 's
693superclasses
694there is an external object
695.IP
696.B const union
697.IB A __vtu_ i
698.IB C __vtable_ i ;
699.PP
700where
701.I A
702and
703.I I
704are respectively the most and least specific classes in the chain.
705.PP
706The first member in the
707.B vt
708structure is the
709.I root class pointer
710.IP
711.B const
712.IR P
713.B *_class;
714.PP
715Among the superclasses of
716.I C
717there must be exactly one class
718.I O
719which itself has no direct superclasses;
720this is the
721.I root superclass
722of
723.IR C .
724(This is a rule enforced by the Sod translator.)
725The metaclass
726.I R
727of
9c4a4110 728.I O
47de28ae
MW
729is then the
730.I root metaclass
731of
732.IR C .
733The
734.B _class
735member points to the
736.B ichain
737structure of most specific superclass
738.I P
739of
740.I M
741in the same chain as
742.IR R .
743.PP
744This is followed by the
745.I base offset
746.IP
747.B size_t
748.B _base;
749.PP
750which is simply the offset of the
751.B ichain
752structure from the instance base.
753.PP
754The rest of the vtable structure is populated
755by walking the superclass chain containing
756.I C
757as follows.
758For each such superclass
759.IR B ,
760in increasing order of specificity,
761walk the class precedence list of
762.IR B ,
763again starting with its least-specific superclass.
764(This complex procedure guarantees that
765the vtable structure for a class is a prefix of
766the vtable structure for any of its subclasses in the same chain.)
767.PP
768So, let
769.I A
770be some superclass of
771.I C
772which has been encountered during this traversal.
773.hP \*o
774Let
775.I N
776be the metaclass of
777.IR A .
778Examine the superclass chains of
779.I N
780in order of decreasing specificity of their most-specific classes.
781Let
782.I J
783be the chain head of such a chain,
784and let
785.I Q
786be the most specific superclass of
787.I M
788in the same chain as
789.IR J .
790Then, if there is currently no class pointer of type
9c4a4110 791.IR Q ,
47de28ae
MW
792then add a member
793.RS
794.IP
795.B const
796.I Q
797.BI *_cls_ j ;
798.PP
799to the vtable
800pointing to the appropriate
801.B islots
802structure within
803.IR M 's
804class object.
805.RE
806.hP \*o
807Examine the superclass chains of
808.I A
809in order of decreasing specificity of their most-specific classes.
810Let
811.I I
812be the chain head of such a chain.
813If there is currently no member
814.BI _off_ i
815then add a member
816.RS
817.IP
818.B ptrdiff_t
819.BI _off_ i ;
820.PP
821to the vtable,
822containing the (signed) offset from the
823.B ichain
824structure of the chain headed by
825.I h
826to that of the chain headed by
827.I i
828within the instance's layout.
829.RE
830.hP \*o
831If class
832.I A
833defines any messages,
834and there is currently no member
9c4a4110 835.IR a ,
47de28ae
MW
836then add a member
837.RS
838.IP
839.B struct
840.IB C __vtmsgs_ a
841.IB a ;
842.PP
843to the vtable.
844See below.
845.RE
846.PP
847Finally, the
848.B vtmsgs
849structures contain pointers to the effective method entry functions
850for the messages defined by a superclass.
851There may be more than one method entry for a message,
852but all of the entry pointers for a message appear together,
853and entry pointers for separate messages appear
854in the order in which the messages are defined.
855If the receiver class has no applicable primary method for a message
856then it's usual for the method entry pointer to be null
857(though, as with a lot of things in Sod,
858extensions may do something different).
859.PP
860For a standard message which takes a fixed number of arguments,
861defined as
862.IP
863.I tr
864.IB m ( \c
865.I t1
866.IB a1 ,
867.RB ... ,
868.I tn
869.IB an );
870.PP
871there is always a `main' entry point,
872.IP
873.I tr
874.BI (* m )( \c
875.I C
876.BI * me ,
877.I t1
878.IB a1 ,
879.RB ... ,
880.I tn
881.IB an );
882.PP
883For a standard message which takes a variable number of arguments,
884defined as
885.IP
886.I tr
887.IB m ( \c
888.I t1
889.IB a1 ,
890.RB ... ,
891.I tn
892.IB an ,
893.B ...);
894.PP
895two entry points are defined:
896the usual `main' entry point
897which accepts a variable number of
898arguments,
899and a `valist' entry point
900which accepts an argument of type
901.B va_list
902in place of the variable portion of the argument list.
903.IP
904.I tr
905.BI (* m )( \c
906.I C
907.BI * me ,
908.I t1
909.IB a1 ,
910.RB ... ,
911.I tn
912.IB an ,
913.B ...);
914.br
915.I tr
916.BI (* m __v)( \c
917.I C
918.BI * me ,
919.I t1
920.IB a1 ,
921.RB ... ,
922.I tn
923.IB an ,
924.B va_list
925.IB sod__ap );
926.
927.SS Additional definitions
928In addition to the instance and vtable structures described above,
929the following definitions are made for each class
930.IR C .
931.PP
932For each message
933.I m
934directly defined by
935.I C
936there is a macro definition
937.IP
938.B #define
939.IB C _ m ( me ,
940.RB ... )
941.IB me ->_vt-> c . m ( me ,
942.RB ... )
943.PP
944which makes sending the message
945.I m
946to an instance of (any subclass of)
947.I C
948somewhat less ugly.
949If
950.I m
951takes a variable number of arguments,
952the macro is more complicated
953and is only available in compilers advertising C99 support,
954but the effect is the same.
955For each variable-argument message,
956there is also an additional macro
957for calling the `valist' entry point.
958.IP
959.B #define
960.IB C _ m __v( me ,
961.RB ...,
962.IB sod__ap )
963.if !t \{\
964\e
965.br
966\h'4m'\c
967.\}
968.IB me ->_vt-> c . m __v( me ,
969.RB ...,
970.IB sod__ap )
971.PP
972For each proper superclass
973.I A
974of
975.IR C ,
976there is a macro defined
977.IP
978.I A
979.BI * C __CONV_ a ( C
980.BI * _obj );
981.PP
982(named in
983.IR "upper case" )
984which converts a (static-type) pointer to
985.I C
986to a pointer to the same actual instance,
987but statically typed as a pointer to
988.IR A .
989This is most useful when
990.I A
991is not in the same chain as
992.I C
993since in-chain upcasts are both trivial and rarely needed,
994but the full set is defined for the sake of completeness.
995.PP
996Finally, the class object is defined as
997.IP
998.B extern const struct
999.IB R __ilayout
1000.IB C __classobj;
1001.br
1002.B #define
1003.IB C __class
1004.BI (& C __classobj. j . r )
1005.PP
1006The exported symbol
1007.IB C __classobj
1008contains the entire class instance.
1009This is usually rather unwieldy.
1010The macro
1011.IB C __class
1012is usable as a pointer of type
1013.B const
1014.I R
1015.BR * ,
1016where
1017.I R
1018is the root metaclass of
1019.IR C ,
1020i.e., the metaclass of the least specific superclass of
1021.IR C ;
1022usually this is
1023.BR "const SodClass *" .
1024.
1025.\"--------------------------------------------------------------------------
1026.SH SEE ALSO
1027.BR sod (3).
1028.
1029.\"--------------------------------------------------------------------------
1030.SH AUTHOR
1031Mark Wooding, <mdw@distorted.org.uk>
1032.
1033.\"----- That's all, folks --------------------------------------------------