lib/sod.h (sod_sublassp): Fix function description.
[sod] / lib / sod.h
index faffb20..3ad4250 100644 (file)
--- a/lib/sod.h
+++ b/lib/sod.h
@@ -104,7 +104,7 @@ SOD__VARARGS_MACROS_PREAMBLE
 #  define SOD__ALIGNOF(type) __alignof__(type)
 #else
 #  define SOD__ALIGNOF(type)                                           \
-offsetof(struct { char sod__x; type sod__y; }, sod__y)
+       offsetof(struct { char sod__x; type sod__y; }, sod__y)
 #endif
 
 /* --- @SOD__IGNORE@ --- *
@@ -116,6 +116,35 @@ offsetof(struct { char sod__x; type sod__y; }, sod__y)
 
 #define SOD__IGNORE(var) ((void)(var))
 
+/* --- @SOD__NORETURN@ --- *
+ *
+ * Use:                Marks functions which are not expected to return.
+ */
+
+#if SOD__GCC_P(2, 5)
+#  define SOD__NORETURN __attribute__((__noreturn__))
+#endif
+
+#ifndef SOD__NORETURN
+#  define SOD__NORETURN
+#endif
+
+/* --- @SOD__PARANOIA@ --- *
+ *
+ * Arguments:  @cond@ = a condition to check
+ *             @conseq@ = a thing to evaluate to if the check passes
+ *             @alt@ = a thing to do if the check fails
+ *
+ * Use:                Check to make sure something is good at runtime, unless
+ *             disabled.
+ */
+
+#if SOD_RECKLESS
+#  define SOD__PARANOIA(cond, conseq, alt) (conseq)
+#else
+#  define SOD__PARANOIA(cond, conseq, alt) ((cond) ? (conseq) : (alt))
+#endif
+
 /* --- @SOD__CAR@ --- *
  *
  * Arguments:  @...@ = a nonempty list of arguments
@@ -291,7 +320,7 @@ struct sod_chain {
 
 /* --- @SOD_DECL@ --- *
  *
- * Arguments:  @cls@ = a class type name
+ * Arguments:  @cls_@ = a class type name
  *             @var@ = a variable name
  *             @keys@ = a @KWARGS(...)@ keyword argument sequence
  *
@@ -299,17 +328,36 @@ struct sod_chain {
  *             @cls@ with automatic lifetime.
  */
 
-#define SOD_DECL(cls, var, keys)                                       \
-  struct cls##__ilayout var##__layout;                                 \
-  cls *var = (cls *)sod_init(cls##__class, &var##__layout, keys)
+#define SOD_DECL(cls_, var, keys)                                      \
+  struct cls_##__ilayout var##__layout;                                        \
+  cls_ *var =                                                          \
+    SOD__PARANOIA(sizeof(var##__layout) == cls_##__class->cls.initsz,  \
+                 (cls_ *)sod_init(cls_##__class, &var##__layout, keys), \
+                 (sod__chksz_fail(cls_##__class, sizeof(var##__layout)), \
+                  (cls_ *)0))
 
 /*----- Functions provided ------------------------------------------------*/
 
+/* --- @sod__chksz_fail@ --- *
+ *
+ * Arguments:  @const SodClass *cls@ = class we were trying to instantiate
+ *             @size_t sz@ = size allocated
+ *
+ * Returns:    Doesn't.
+ *
+ * Use:                Reports instantiation failure caused by a mismatch between
+ *             the size allocated (@sz@) and the size required for an
+ *             instance of class @cls@.
+ */
+
+extern SOD__NORETURN
+  void sod__chksz_fail(const SodClass */*cls*/, size_t /*sz*/);
+
 /* --- @sod_subclassp@ --- *
  *
  * Arguments:  @const SodClass *sub, *super@ = pointers to two classes
  *
- * Returns:    Nonzero if @c@ is a subclass of @d@.
+ * Returns:    Nonzero if @sub@ is a subclass of @super@.
  */
 
 extern int sod_subclassp(const SodClass */*sub*/, const SodClass */*super*/);