doc/misc.tex: Document many utilities.
[sod] / doc / runtime.tex
index 4178c43..7ca8cbd 100644 (file)
@@ -34,7 +34,8 @@ described in \xref{ch:structures}.
 
 This section describes the types, macros, and functions exposed in the
 @|<sod/keyword.h>| header file which provides support for defining and
-calling functions which make use of keyword arguments; see \xref{sec:concepts.keywords}.
+calling functions which make use of keyword arguments; see
+\xref{sec:concepts.keywords}.
 
 
 \subsection{Type definitions} \label{sec:sec:runtime.keywords.types}
@@ -42,10 +43,10 @@ calling functions which make use of keyword arguments; see \xref{sec:concepts.ke
 The header file defines two simple structure types, and a function type which
 will be described later.
 
-\begin{describe}[struct kwval]{type}
-    {struct kwval \{ \\ \ind
-       const char *kw; \\
-       const void *val; \- \\
+\begin{describe}{type}[struct kwval]
+    {struct kwval \{                                            \\ \ind
+       const char *kw;                                          \\
+       const void *val;                                       \-\\
      \};}
 
   The @|kwval| structure describes a keyword argument name/value pair.  The
@@ -55,10 +56,10 @@ will be described later.
   the actual argument type.)
 \end{describe}
 
-\begin{describe}[struct kwtab]{type}
-    {struct kwtab \{ \\ \ind
-       const struct kwval *v; \\
-       size_t n; \- \\
+\begin{describe}{type}[struct kwtab]
+    {struct kwtab \{                                            \\ \ind
+       const struct kwval *v;                                   \\
+       size_t n;                                              \-\\
      \};}
 
   The @|kwtab| structure describes a list of keyword arguments, represented
@@ -136,7 +137,7 @@ result will be unbounded recursion or some other bad outcome.
 The following macros are intended to help with constructing keyword argument
 lists.  Their use is not essential, but may help prevent errors.
 
-\begin{describe}[KWARGS]{mac}{KWARGS(@<body>)}
+\begin{describe}{mac}[KWARGS]{KWARGS(@<body>)}
   The @<body> encloses a sequence of keyword arguments expressed as calls to
   argument consists of a sequence of calls to the keyword-argument macros
   described below, one after another without any separation.
@@ -158,18 +159,18 @@ lists.  Their use is not essential, but may help prevent errors.
 The following keyword-argument macros can be used within the @|KWARGS|
 @<body> argument.
 
-\begin{describe}[K]{mac}{K(@<name>, @<value>)}
+\begin{describe}{mac}[K]{K(@<name>, @<value>)}
   Passes a keyword @<name> and its corresponding @<value>, as a pair of
   arguments.  The @<name> should be a single identifier (not a quoted
   string).  The @<value> may be any C expression of the appropriate type.
 \end{describe}
 
-\begin{describe}[K_VALIST]{mac}{K_VALIST(@<ap>)}
+\begin{describe}{mac}[K_VALIST]{K_VALIST(@<ap>)}
   Passes an indirect variable-length argument tail.  The argument @<ap>
   should be an lvalue of type @|va_list|, which will be passed by reference.
 \end{describe}
 
-\begin{describe}[K_TAB]{mac}{K_TAB(@<v>, @<n>)}
+\begin{describe}{mac}[K_TAB]{K_TAB(@<v>, @<n>)}
   Passes a vector of keyword arguments.  The argument @<v> should be the base
   address of the vector, and @<n> should be the number of elements in the
   vector.
@@ -203,8 +204,8 @@ list items of the form
 \end{prog}
 with no separation between them.  For example:
 \begin{prog}
-  \#define example_KWSET(_) @\\ \\ \ind
-    _(int, x, 0) @\\ \\
+  \#define example_KWSET(_)                             \macsl  \\ \ind
+    _(int, x, 0)                                        \macsl  \\
     _(const char *, y, NULL)
 \end{prog}
 
@@ -261,7 +262,7 @@ definitions of functions which accept keyword arguments.
 The following macros define data types and functions used for collecting
 keyword arguments.
 
-\begin{describe}[KWSET_STRUCT]{mac}{KWSET_STRUCT(@<set>);}
+\begin{describe}{mac}[KWSET_STRUCT]{KWSET_STRUCT(@<set>);}
   The @|KWSET_STRUCT| macro defines a \emph{keyword structure} named @|struct
   @<set>{}_kwargs|.  For each argument defined in the keyword set, this
   structure contains two members: one has exactly the @<name> and @<type>
@@ -269,7 +270,7 @@ keyword arguments.
   type @|unsigned int| named @|@<name>{}_suppliedp|.
 \end{describe}
 
-\begin{describe}[KWDECL]{mac}
+\begin{describe}{mac}[KWDECL]
     {@<declaration-specifiers> KWDECL(@<set>, @<kw>);}
   The macro declares and initializes a keyword argument structure variable
   named @<kw> for the named keyword @<set>.  The optional
@@ -279,15 +280,16 @@ keyword arguments.
   corresponding defaults from the keyword-set definition.
 \end{describe}
 
-\begin{describe}[KWSET_PARSEFN]{mac}
+\begin{describe}{mac}[KWSET_PARSEFN]
     {@<declaration-specifiers> KWSET_PARSEFN(@<set>)}
 
   The macro @|KWSET_PARSEFN| defines a keyword argument \emph{parser
   function}
   \begin{prog}
-    void @<set>{}_kwparse(\=struct @<set>{}_kwargs *@<kw>,
-                            const char *@<kwfirst>, va_list *@<ap>, \+ \\
-                            const struct kwval *@<v>, size_t @<n>);
+    void @<set>{}_kwparse%
+      (\=struct @<set>{}_kwargs *@<kw>,
+         const char *@<kwfirst>, va_list *@<ap>,              \+\\
+         const struct kwval *@<v>, size_t @<n>);
   \end{prog}
   The macro call can (and usually will) be preceded by storage class
   specifiers such as @|static|, for example to adjust the linkage of the
@@ -311,7 +313,7 @@ keyword arguments.
   purpose, the argument vector @<v> is scanned \emph{after} the
   variable-length argument tail captured in @<ap>.)
 
-  The variable-argument tail is read from the list described by @|* @<ap>|.
+  The variable-argument tail is read from the list described by @|*@<ap>|.
   The argument tail is expected to consist of alternating keyword strings (as
   ordinary null-terminated strings) and the corresponding values, terminated
   by a null pointer of type @|const char~*| in place of a keyword; except
@@ -327,7 +329,7 @@ keyword arguments.
     which expects keyword arguments, but don't supply any and forget the null
     pointer which terminates the (empty) list.} %
   If @<kwfirst> is a null pointer, then @<ap> need not be a valid pointer;
-  otherwise, the cursor object @|* @<ap>| will be modified as the function
+  otherwise, the cursor object @|*@<ap>| will be modified as the function
   extracts successive arguments from the tail.
 
   The keyword vector is read from the vector of @|kwval| structures starting
@@ -343,7 +345,7 @@ keyword arguments.
 The following macros make use of the definitions described above to actually
 make a function's keyword arguments available to it.
 
-\begin{describe}[KW_PARSE]{mac}{KW_PARSE(@<set>, @<kw>, @<kwfirst>);}
+\begin{describe}{mac}[KW_PARSE]{KW_PARSE(@<set>, @<kw>, @<kwfirst>);}
   The @|KW_PARSE| macro invokes a keyword argument parsing function.  The
   @<set> argument should name a keyword set; @<kw> should be an lvalue of
   type @|struct @<set>{}_kwargs|; and @<kwfirst> should be the name of the
@@ -364,7 +366,7 @@ make a function's keyword arguments available to it.
   appropriately.
 \end{describe}
 
-\begin{describe}[KWPARSE]{mac}{KWPARSE(@<set>);}
+\begin{describe}{mac}[KWPARSE]{KWPARSE(@<set>);}
   The macro @|KWPARSE| (note the lack of underscore) combines
   \descref{KWDECL}{mac} and \descref{KW_PARSE}{mac}.  It declares and
   initializes a keyword argument structure variable with the fixed name
@@ -394,7 +396,7 @@ mechanism, and it's useful to be able to define a function which doesn't
 currently accept any keywords, but which might in the future be extended to
 allow keyword arguments.
 
-\begin{describe}[KW_PARSE_EMPTY]{mac}{KW_PARSE_EMPTY(@<set>, @<kwfirst>);}
+\begin{describe}{mac}[KW_PARSE_EMPTY]{KW_PARSE_EMPTY(@<set>, @<kwfirst>);}
   This is an analogue to \descref{KW_PARSE}{mac} which checks the keyword
   argument list for a function which accepts no keyword arguments.
 
@@ -409,17 +411,18 @@ allow keyword arguments.
   other than the special predefined ones.
 \end{describe}
 
-\begin{describe}[KWPARSE_EMPTY]{mac}{KWPARSE_EMPTY(@<set>);}
+\begin{describe}{mac}[KWPARSE_EMPTY]{KWPARSE_EMPTY(@<set>);}
   This is an analogue to \descref{KWPARSE}{mac} which checks that the
   enclosing function has been passed no keyword arguments other than the
   special predefined ones.  It assumes that the first keyword name is in an
   argument named @|kwfirst_|, as set up by the \descref{KWTAIL}[marker]{mac}.
 \end{describe}
 
-\begin{describe}[kw_parseempty]{fun}
-    {void kw_parseempty(\=const char *@<set>,
-                          const char *@<kwfirst>, va_list *@<ap>, \+ \\
-                          const struct kwval *@<v>, size_t @<n>);}
+\begin{describe}{fun}[kw_parseempty]
+    {void kw_parseempty%
+      (\=const char *@<set>,
+         const char *@<kwfirst>, va_list *@<ap>,              \+\\
+         const struct kwval *@<v>, size_t @<n>);}
   This function checks an keyword argument list to make sure that contains no
   keyword arguments (other than the special ones described in
   \xref{sec:runtime.keywords.calling}).
@@ -447,11 +450,11 @@ depending on the corresponding @`_suppliedp' flags.
 
 A few macros are provided to make this task easier.
 
-\begin{describe}[KW_COUNT]{mac}{KW_COUNT(@<set>)}
+\begin{describe}{mac}[KW_COUNT]{KW_COUNT(@<set>)}
   Returns the number of keywords defined in a keyword set named @<set>.
 \end{describe}
 
-\begin{describe}[KW_COPY]{mac}
+\begin{describe}{mac}[KW_COPY]
     {KW_COPY(@<fromset>, @<toset>, @<kw>, @<v>, @<n>);}
 
   The macro @|KW_COPY| populates a vector of @|kwval| structures from a
@@ -492,7 +495,7 @@ In this situation, the parser functions generated by
 \descref{KWSET_PARSEFN}{mac} (and the \descref{kw_parseempty}[function]{fun})
 call @|kw_unknown|.
 
-\begin{describe}[kw_unknown]{fun}
+\begin{describe}{fun}[kw_unknown]
     {void kw_unknown(const char *@<set>, const char *@<kw>);}
 
   This is a function of two arguments: @<set> points to the name of the
@@ -506,7 +509,7 @@ call @|kw_unknown|.
   message to the standard error stream and calls \man{abort}{3}.
 \end{describe}
 
-\begin{describe}[kw_unkhookfn]{type}
+\begin{describe}{type}[kw_unkhookfn]
     {typedef void kw_unkhookfn(const char *@<set>, const char *@<kw>);}
 
   The @|kw_unkhookfn| type is the type of unknown-keyword handler functions.
@@ -515,7 +518,7 @@ call @|kw_unknown|.
   and @<kw> is the name of the offending unknown keyword.
 \end{describe}
 
-\begin{describe}[kw_unkhook]{var}{kw_unkhookfn *kw_unkhook}
+\begin{describe}{var}[kw_unkhook]{kw_unkhookfn *kw_unkhook}
   This variable\footnote{%
     Having a single global hook variable is obviously inadequate for a modern
     library, but dealing with multiple threads isn't currently possible
@@ -535,7 +538,7 @@ call @|kw_unknown|.
   \descref{kw_defunknown}[function]{fun}.
 \end{describe}
 
-\begin{describe}[kw_defunknown]{fun}
+\begin{describe}{fun}[kw_defunknown]
     {void kw_defunknown(const char *@<set>, const char *@<kw>);}
   This function simply writes a message to standard error, to the effect that
   the keyword named by @<kw> is not known in the keyword set @<set>, and
@@ -551,32 +554,33 @@ particular keyword argument.
 
 \begin{prog}
   \#define KWARGS_TEST(k, val) KWARGS(K(k, val) K(kw.unknown, 0))
-  \\+
+                                                                \\+
   static jmp_buf kw_test_jmp;
-  \\+
-  static void kw_test_unknown(const char *set, const char *kw) \\
-  \{ \\ \ind
-    if (strcmp(kw, "kw.unknown")) longjmp(kw_test_jmp, 1); \\
-    else longjmp(kw_test_jmp, 2); \- \\
-  \}
-  \\+
-  \#define KW_TEST(flag, set, call) do \{ @\\ \\ \ind
-    kw_unkhookfn *oldunk = kw_unkhook; @\\ \\
-    kw_unkhook = kw_test_unknown; @\\ \\
-    switch (setjmp(kw_test_jmp)) \{ @\\ \\ \ind
-      case 0: call; abort(); @\\ \\
-      case 1: flag = 1; break; @\\ \\
-      case 2: flag = 0; break; @\\ \\
-      default: abort(); \- @\\ \\
-    \} @\\ \\
-    kw_unkhook = oldunk; \- @\\ \\
-  \} while (0)
-  \\+
-  /* Example of use */ \\
-  int f; \\
+                                                                \\+
+  static void kw_test_unknown(const char *set, const char *kw)  \\
+  \{                                                            \\ \ind
+    if (strcmp(kw, "kw.unknown")) longjmp(kw_test_jmp, 1);      \\
+    else longjmp(kw_test_jmp, 2);                             \-\\
+  \}                                                            \\+
+
+  \#define KW_TEST(flag, set, call) do \{               \macsl  \\ \ind
+    kw_unkhookfn *oldunk = kw_unkhook;                  \macsl  \\
+    kw_unkhook = kw_test_unknown;                       \macsl  \\
+    switch (setjmp(kw_test_jmp)) \{                     \macsl  \\ \ind
+      case 0: call; abort();                            \macsl  \\
+      case 1: flag = 1; break;                          \macsl  \\
+      case 2: flag = 0; break;                          \macsl  \\
+      default: abort();                                 \macsl\-\\
+    \}                                                  \macsl  \\
+    kw_unkhook = oldunk;                                \macsl\-\\
+  \} while (0)                                                  \\+
+
+  @/* Example of use */                                         \\
+  int f;                                                        \\
   KW_TEST(f, somefunc(1, "two", 3, KWARGS_TEST("shiny", 68.7))); \\
-  /\=* now f is nonzero if `somefunc' accepts the `shiny' keyword \+ \\
-   {}* (which we hope wants a double argument) \\
+  /\=* \comment{now @|f| is nonzero if @|somefunc| accepts the
+        @|shiny| keyword}                                     \+\\
+   {}* \comment{(which we hope wants a @|double| argument)}     \\
    {}*/
 \end{prog}
 
@@ -593,33 +597,19 @@ While the translator can (at some effort) support alternative roots, they
 will require different run-time support machinery.
 
 
-\subsection{Infrastructure macros} \label{ch:runtime.object.infra}
+\subsection{Layout utilities} \label{sec:runtime.object.layout}
 
-The runtime support functionality defined here generally expects that
-instances and classes inherit from the standard @|SodObject| root object.
-While the translator can (at some effort) support alternative roots, they
-will require different run-time support machinery.
+The following macros are useful in finding one's way around an instance
+layout structure, given various levels of information about what kind of
+object one is dealing with, or for computing the tables which are used for
+this kind of navigation.
 
 These macros are mostly intended for use in code generated by the Sod
 translator.  Others may find them useful for special effects, but they can be
 tricky to understand and use correctly and can't really be recommended for
 general use.
 
-\begin{describe}[SOD_XCHAIN]{mac}
-    {void *SOD_CHAIN(@<chead>, const @<cls> *@<obj>);}
-  Performs a `cross-chain upcast'.
-
-  Given a pointer @<obj> to an instance of a class of type @<cls> and the
-  nickname @<chead> of the least specific class in one of @<cls>'s superclass
-  chains which does not contain @<cls> itself, @|SOD_XCHAIN| returns the
-  address of that chain's storage within the instance layout as a raw
-  @|void~*| pointer.  (Note that @<cls> is not mentioned explicitly.)
-
-  This macro is used by the generated @|@<CLASS>{}__CONV_@<CLS>| conversion
-  macros, which you are encouraged to use instead where possible.
-\end{describe}
-
-\begin{describe}[SOD_OFFSETDIFF]{mac}
+\begin{describe}{mac}[SOD_OFFSETDIFF]
     {ptrdiff_t SOD_OFFSETDIFF(@<type>, @<member>_1, @<member>_2);}
   Returns the signed offset between two members of a structure or union type.
 
@@ -632,7 +622,7 @@ general use.
   to be very useful elsewhere.
 \end{describe}
 
-\begin{describe}[SOD_ILAYOUT]{mac}
+\begin{describe}{mac}[SOD_ILAYOUT]
     {@<cls>{}__ilayout *SOD_ILAYOUT(@<cls>, @<chead>, const void *@<obj>);}
   Recovers the instance layout base address from a pointer to one of its
   instance chains.
@@ -650,23 +640,7 @@ general use.
   @|SOD_INSTBASE| macro (described below) is more suited to general use.
 \end{describe}
 
-
-\subsection{Utility macros} \label{sec:runtime.object.utility}
-
-The following macros are expected to be useful in Sod method definitions and
-client code.
-
-\begin{describe}[SOD_CLASSOF]{mac}
-    {const void *SOD_CLASSOF(const @<cls> *@<obj>);}
-  Returns the class object describing an instance's dynamic class.
-
-  Given a pointer @<obj> to an instance, @|SOD_CLASSOF| returns a pointer to
-  @<obj>'s dynamic class, which (assuming @<obj> is typed correctly in the
-  first place) will be a subclass of @<cls>.  (If you wanted the class object
-  for @<cls> itself, it's called @|@<cls>{}__class|.)
-\end{describe}
-
-\begin{describe}[SOD_INSTBASE]{mac}{void *SOD_INSTBASE(const @<cls> *@<obj>)}
+\begin{describe}{mac}[SOD_INSTBASE]{void *SOD_INSTBASE(const @<cls> *@<obj>)}
   Finds the base address of an instance's layout.
 
   Given a pointer @<obj> to an instance, @|SOD_INSTBASE| returns the base
@@ -678,41 +652,23 @@ client code.
   knowledge of the instance's dynamic class.
 \end{describe}
 
-\begin{describe}[SOD_CONVERT]{mac}
-    {@<cls> *SOD_CONVERT(@<cls>, const void *@<obj>);}
-
-  Perform general conversions (up-, down-, and cross-casts) on instance
-  pointers.
 
-  Given a class name @<cls> and a pointer @<obj> to an instance,
-  @|SOD_CONVERT| returns an appropriately converted pointer to @<obj> if
-  @<obj> is indeed an instance of (some subclass of) @<cls>; otherwise it
-  returns a null pointer.
+\subsection{Classes} \label{sec:runtime.object.class}
 
-  This macro is a simple wrapper around the @|sod_convert| function described
-  below, which is useful in the common case that the target class is known
-  statically.
-\end{describe}
-
-\begin{describe}[SOD_DECL]{mac}{SOD_DECL(@<cls>, @<var>);}
-  Declares and initializes an instance with automatic storage duration.
+The following macros and functions query the runtime relationships between
+instances and classes.
 
-  Given a class name @<cls> and an identifier @<var>, @|SOD_DECL| declares
-  @<var> to be a pointer to an instance of @<cls>.  The instance is
-  initialized in the sense that its vtable and class pointers have been set
-  up, and slots for which initializers are defined are set to the appropriate
-  initial values.
+\begin{describe}{mac}[SOD_CLASSOF]
+    {const SodClass *SOD_CLASSOF(const @<cls> *@<obj>);}
+  Returns the class object describing an instance's dynamic class.
 
-  The instance has automatic storage duration: pointers to it will become
-  invalid when control exits the scope of the declaration.
+  Given a pointer @<obj> to an instance, @|SOD_CLASSOF| returns a pointer to
+  @<obj>'s dynamic class, which (assuming @<obj> is typed correctly in the
+  first place) will be a subclass of @<cls>.  (If you wanted the class object
+  for @<cls> itself, it's called @|@<cls>{}__class|.)
 \end{describe}
 
-
-\subsection{Functions} \label{sec:runtime.object.functions}
-
-The following functions are provided in @|libsod|.
-
-\begin{describe}[sod_subclassp]{fun}
+\begin{describe}{fun}[sod_subclassp]
     {int sod_subclassp(const SodClass *@<sub>, const SodClass *@<super>);}
 
   Decide whether one class @<sub> is actually a subclass of another class
@@ -725,23 +681,164 @@ The following functions are provided in @|libsod|.
   effort has been made to make it perform well it's still not very fast.
 \end{describe}
 
-\begin{describe}[sod_convert]{fun}
-    {void *sod_convert(const SodClass *@<cls>, const void *@<obj>);}
-  Performs general conversions (up-, down-, and cross-casts) on instance
+
+\subsection{Conversions} \label{sec:runtime.object.conversions}
+
+The following macros and functions are used to convert instance pointers of
+some (static) type into instance pointers of other static types to the same
+instance.
+
+\begin{describe}{mac}[SOD_XCHAIN]
+    {void *SOD_XCHAIN(@<chead>, const @<cls> *@<obj>);}
+  Performs a `cross-chain upcast'.
+
+  Given a pointer @<obj> to an instance of a class of type @<cls> and the
+  nickname @<chead> of the least specific class in one of @<cls>'s superclass
+  chains which does not contain @<cls> itself, @|SOD_XCHAIN| returns the
+  address of that chain's storage within the instance layout as a raw
+  @|void~*| pointer.  (Note that @<cls> is not mentioned explicitly.)
+
+  This macro is used by the generated @|@<cls>{}__CONV_@<c>| conversion
+  macros, which you are encouraged to use instead where possible.
+\end{describe}
+
+\begin{describe*}
+    {\dhead{mac}[SOD_CONVERT]
+       {@<cls> *SOD_CONVERT(@<cls>, const void *@<obj>);}
+     \dhead{fun}[sod_convert]
+       {void *sod_convert(const SodClass *@<cls>, const void *@<obj>);}}
+  Perform general conversions (up-, down-, and cross-casts) on instance
   pointers.
 
-  Given a class pointer @<cls> and an instance pointer @<obj>, @|sod_convert|
-  returns an appropriately converted pointer to @<obj> in the case that
-  @<obj> is an instance of (some subclass of) @<cls>; otherwise it returns
-  null.
+  Given a class @<cls> and a pointer @<obj> to an instance, return an
+  appropriately converted pointer to @<obj> if @<obj> is indeed an instance
+  of (some subclass of) @<cls>; otherwise return a null pointer.
+
+  The @|SOD_CONVERT| macro expects @<cls> to be a class name; the
+  @|sod_convert| function expects a pointer to a class object instead.
 
   This involves a run-time trawl through the class structures: while some
   effort has been made to make it perform well it's still not very fast.  For
   upcasts (where @<cls> is a superclass of the static type of @<obj>) the
   automatically defined conversion macros should be used instead, because
-  they're much faster and can't fail.  When the target class is known
-  statically, it's slightly more convenient to use the @|SOD_CONVERT| macro
-  instead.
+  they're much faster and can't fail.
+
+  When the target class is known statically, it's slightly more convenient to
+  use the @|SOD_CONVERT| macro than the @|sod_convert| function, since the
+  class object name is longer and uglier, and the macro returns a pointer of
+  the correct type.
+\end{describe*}
+
+
+\subsection{Instance lifecycle}
+\label{sec:runtime.object.lifecycle}
+
+The following macros and functions manage the standard steps along an
+instance's lifecycle.
+
+\subsubsection{Low-level operations}
+The following macros and functions are agnostic with respect to storage
+allocation strategies.  They don't concern themselves with allocation or
+deallocation, and applications are free to use any suitable mechanism.
+
+\begin{describe*}
+    {\dhead{mac}[SOD_INIT]
+       {@<cls> *SOD_INIT(@<cls>, void *@<p>, @<keywords>);}
+     \dhead{fun}[sod_init]
+       {void *sod_init(const SodClass *@<cls>, void *@<p>, \dots);}
+     \dhead{fun}[sod_initv]
+       {void *sod_initv(const SodClass *@<cls>, void *@<p>, va_list @<ap>);}}
+  Imprints and initializes an instance of a class @<cls> in the storage
+  starting at address~@<p>.
+
+  The direct class for the new instance is specified as a class name to
+  @|SOD_INIT|, or a pointer to a class object to the functions.
+
+  Keyword arguments for the initialization message may be provided.  The
+  @|SOD_INIT| macro expects a single preprocessor-time argument which is
+  a use of one of \descref{KWARGS}{mac} or \descref{NO_KWARGS}{mac}; the
+  @|sod_init| function expects the keywords as a variable-length argument
+  tail; and @|sod_initv| expects the keywords to be passed indirectly,
+  through the captured argument-tail cursor @<ap>.
+
+  The return value is an instance pointer for the class @<cls>; the
+  @|SOD_INIT| macro will have converted it to the correct type, so it should
+  probably be used where possible.  In fact, this is guaranteed to be equal
+  to @<p> by the layout rules described in
+  \xref{sec:structures.layout.instance}.
+\end{describe*}
+
+\begin{describe}{fun}[sod_teardown]{int sod_teardown(void *@<p>);}
+  Tears down an instance of a class, releasing any resources it holds.
+
+  This function is a very thin wrapper around sending the @|obj.teardown|
+  message.  See the description of that message
+  (page~\pageref{msg:obj.teardown}) and \xref{sec:concepts.lifecycle.death}
+  for details.
+\end{describe}
+
+\subsubsection{Automatic storage duration}
+The following macro constructs an instance with automatic storage duration.
+
+\begin{describe}{mac}[SOD_DECL]{SOD_DECL(@<cls>, @<var>, @<keywords>);}
+  Declares and initializes an instance with automatic storage duration.
+
+  Given a class name @<cls> and an identifier @<var>, @|SOD_DECL| declares
+  @<var> to be a pointer to an instance of @<cls>.  The instance is
+  initialized in the sense that its vtable and class pointers have been set
+  up, and slots for which initializers are defined are set to the appropriate
+  initial values.
+
+  Keyword arguments for the initialization message may be provided.  The
+  macro expects a single preprocessor-time argument which is a use of one of
+  \descref{KWARGS}{mac} or \descref{NO_KWARGS}{mac}.
+
+  The instance has automatic storage duration: pointers to it will become
+  invalid when control exits the scope of the declaration.  If necessary, the
+  instance should be torn down before this happens, using the
+  \descref{sod_teardown}[function]{fun}.
+\end{describe}
+
+\subsubsection{Dynamic allocation}
+The following macros and functions deal with objects allocated from the
+standard C heap.  They don't work in freestanding implementations where
+@|malloc| and @|free| are not available.
+
+\begin{describe*}
+    {\dhead{mac}[SOD_MAKE]{@<cls> *SOD_MAKE(@<cls>, @<keywords>);}
+     \dhead{fun}[sod_make]{void *sod_make(const SodClass *@<cls>, \dots);}
+     \dhead{fun}[sod_makev]
+       {void *sod_makev(const SodClass *@<cls>, va_list @<ap>);}}
+  Constructs and returns a pointer to a new instance of @<cls>.
+
+  The direct class for the new instance is specified as a class name to
+  @|SOD_MAKE|, or a class object to the functions.
+
+  Keyword arguments for the initialization message may be provided.  The
+  @|SOD_MAKE| macro expects a single preprocessor-time argument which is
+  a use of one of \descref{KWARGS}{mac} or \descref{NO_KWARGS}{mac}; the
+  @|sod_make| function expects the keywords as a variable-length argument
+  tail; and @|sod_makev| expects the keywords to be passed indirectly,
+  through the captured argument-tail cursor @<ap>.
+
+  Storage for the new instance will have been allocated using the standard
+  @|malloc| function.  The easiest way to destroy the instance, when it is no
+  longer needed, is probably to call the
+  \descref{sod_destroy}[function]{fun}.
+
+  The return value is an instance pointer for the class @<cls>; the
+  @|SOD_MAKE| macro will have converted it to the correct type, so it should
+  probably be used where possible.
+\end{describe*}
+
+\begin{describe}{fun}[sod_destroy]{int sod_destroy(void *@<p>);}
+  Tears down and frees an instance allocated using @|malloc|.
+
+  The pointer @<p> should be an instance pointer, i.e., a pointer to any of
+  an instance's chains.  The instance is torn down, by sending it the
+  \descref{obj.teardown}[message]{msg}.  If the instance reports itself ready
+  for deallocation, then its storage is released using @|free|.  The return
+  value is the value returned by the @|obj.teardown| message.
 \end{describe}
 
 %%%----- That's all, folks --------------------------------------------------