diff --git a/contrib/hstore/hstore_compat.c b/contrib/hstore/hstore_compat.c
index 88764b1b698947e3a5c8903e3be53c652282c029..6327a8e8bb58a5c6e32e8884690ee5b5ece53417 100644
--- a/contrib/hstore/hstore_compat.c
+++ b/contrib/hstore/hstore_compat.c
@@ -94,7 +94,7 @@
  * etc. are compatible.
  *
  * If the above statement isn't true on some bizarre platform, we're
- * a bit hosed (see Assert in hstoreValidOldFormat).
+ * a bit hosed (see StaticAssertStmt in hstoreValidOldFormat).
  */
 typedef struct
 {
@@ -180,7 +180,8 @@ hstoreValidOldFormat(HStore *hs)
 		return 0;
 
 	/* New format uses an HEntry for key and another for value */
-	Assert(sizeof(HOldEntry) == (2 * sizeof(HEntry)));
+	StaticAssertStmt(sizeof(HOldEntry) == 2 * sizeof(HEntry),
+					 "old hstore format is not upward-compatible");
 
 	if (count == 0)
 		return 2;
diff --git a/src/include/c.h b/src/include/c.h
index 06f689d35937b13178f263a6d5db6752e8b96a07..bec1eb3da46528f9d0167c4c954c5a34eefb284a 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -690,14 +690,18 @@ typedef NameData *Name;
 
 
 /*
- * Macros to support compile-time assertion checks, if the compiler has them.
+ * Macros to support compile-time assertion checks.
  *
  * If the "condition" (a compile-time-constant expression) evaluates to false,
  * throw a compile error using the "errmessage" (a string literal).
  *
- * gcc 4.6 and up supports _Static_assert(), but it has bizarre syntactic
+ * gcc 4.6 and up supports _Static_assert(), but there are bizarre syntactic
  * placement restrictions.  These macros make it safe to use as a statement
  * or in an expression, respectively.
+ *
+ * Otherwise we fall back on a kluge that assumes the compiler will complain
+ * about a negative width for a struct bit-field.  This will not include a
+ * helpful error message, but it beats not getting an error at all.
  */
 #ifdef HAVE__STATIC_ASSERT
 #define StaticAssertStmt(condition, errmessage) \
@@ -705,8 +709,10 @@ typedef NameData *Name;
 #define StaticAssertExpr(condition, errmessage) \
 	({ StaticAssertStmt(condition, errmessage); true; })
 #else /* !HAVE__STATIC_ASSERT */
-#define StaticAssertStmt(condition, errmessage)
-#define StaticAssertExpr(condition, errmessage) ((void) true)
+#define StaticAssertStmt(condition, errmessage) \
+	((void) sizeof(struct { int static_assert_failure : (condition) ? 1 : -1; }))
+#define StaticAssertExpr(condition, errmessage) \
+	StaticAssertStmt(condition, errmessage)
 #endif /* HAVE__STATIC_ASSERT */
 
 
@@ -716,6 +722,10 @@ typedef NameData *Name;
  * AssertVariableIsOfType() can be used as a statement.
  * AssertVariableIsOfTypeMacro() is intended for use in macros, eg
  *		#define foo(x) (AssertVariableIsOfTypeMacro(x, int), bar(x))
+ *
+ * If we don't have __builtin_types_compatible_p, we can still assert that
+ * the types have the same size.  This is far from ideal (especially on 32-bit
+ * platforms) but it provides at least some coverage.
  */
 #ifdef HAVE__BUILTIN_TYPES_COMPATIBLE_P
 #define AssertVariableIsOfType(varname, typename) \
@@ -725,8 +735,12 @@ typedef NameData *Name;
 	StaticAssertExpr(__builtin_types_compatible_p(__typeof__(varname), typename), \
 	CppAsString(varname) " does not have type " CppAsString(typename))
 #else /* !HAVE__BUILTIN_TYPES_COMPATIBLE_P */
-#define AssertVariableIsOfType(varname, typename)
-#define AssertVariableIsOfTypeMacro(varname, typename) ((void) true)
+#define AssertVariableIsOfType(varname, typename) \
+	StaticAssertStmt(sizeof(varname) == sizeof(typename), \
+	CppAsString(varname) " does not have type " CppAsString(typename))
+#define AssertVariableIsOfTypeMacro(varname, typename) \
+	StaticAssertExpr(sizeof(varname) == sizeof(typename), \
+	CppAsString(varname) " does not have type " CppAsString(typename))
 #endif /* HAVE__BUILTIN_TYPES_COMPATIBLE_P */