Delete C++ implicit constructor for wuffs types
diff --git a/internal/cgen/cgen.go b/internal/cgen/cgen.go
index 9100f23..df2a8ac 100644
--- a/internal/cgen/cgen.go
+++ b/internal/cgen/cgen.go
@@ -336,27 +336,11 @@
 		buf.writes("#if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)\n\n")
 
 		buf.printf("struct wuffs_base__%s__struct {", n)
-		buf.writes(`
-			#ifdef WUFFS_IMPLEMENTATION
-
-			struct {
-				uint32_t magic;
-				uint32_t active_coroutine;
-				wuffs_base__vtable first_vtable;
-			} private_impl;
-
-			#else  // WUFFS_IMPLEMENTATION
-
-			private:
-			union {
-				uint32_t align_as_per_magic_field;
-				uint8_t placeholder[1073741824];  // 1 GiB.
-			} private_impl WUFFS_BASE__POTENTIALLY_UNUSED_FIELD;
-
-			public:
-
-			#endif  // WUFFS_IMPLEMENTATION
-		`)
+		buf.writes("struct {\n")
+		buf.writes("uint32_t magic;\n")
+		buf.writes("uint32_t active_coroutine;\n")
+		buf.writes("wuffs_base__vtable first_vtable;\n")
+		buf.writes("} private_impl;\n\n")
 
 		buf.writes("\n#ifdef __cplusplus\n\n")
 		// TODO: C++ methods.
@@ -925,30 +909,10 @@
 	fullStructName := g.pkgPrefix + structName + "__struct"
 	b.printf("struct %s {\n", fullStructName)
 
-	b.writex(wiStart)
 	if err := g.writeStructPrivateImpl(b, n); err != nil {
 		return err
 	}
 
-	b.writex(wiElse)
-	b.writes("// When WUFFS_IMPLEMENTATION is not defined, this placeholder private_impl is\n")
-	b.writes("// large enough to discourage trying to allocate one on the stack. The sizeof\n")
-	b.writes("// the real private_impl (and the sizeof the real outermost wuffs_foo__bar\n")
-	b.writes("// struct) is not part of the public, stable, memory-safe API. Call\n")
-	b.writes("// wuffs_foo__bar__baz methods (which all take a \"this\"-like pointer as their\n")
-	b.writes("// first argument) instead of fiddling with bar.private_impl.qux fields.\n")
-	b.writes("//\n")
-	b.writes("// Even when WUFFS_IMPLEMENTATION is not defined, the outermost struct still\n")
-	b.writes("// defines C++ convenience methods. These methods forward on \"this\", so that\n")
-	b.writes("// you can write \"bar->baz(etc)\" instead of \"wuffs_foo__bar__baz(bar, etc)\".\n")
-	b.writes("private:\n")
-	b.writes("union {\n")
-	b.writes("uint32_t align_as_per_magic_field;\n")
-	b.writes("uint8_t placeholder[1073741824];  // 1 GiB.\n")
-	b.writes("} private_impl WUFFS_BASE__POTENTIALLY_UNUSED_FIELD;\n\n")
-	b.writes("public:\n")
-	b.writex(wiEnd)
-
 	if n.AsNode().AsRaw().Flags()&a.FlagsPublic != 0 {
 		if err := g.writeCppMethods(b, n); err != nil {
 			return err
@@ -962,7 +926,24 @@
 func (g *gen) writeCppMethods(b *buffer, n *a.Struct) error {
 	structName := n.QID().Str(g.tm)
 	fullStructName := g.pkgPrefix + structName + "__struct"
-	b.writes("#ifdef __cplusplus\n\n")
+	b.writes("#ifdef __cplusplus\n")
+
+	b.writes("#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)\n")
+	b.writes("// Disallow constructing or copying an object via standard C++ mechanisms,\n")
+	b.writes("// e.g. the \"new\" operator, as this struct is intentionally opaque. Its total\n")
+	b.writes("// size and field layout is not part of the public, stable, memory-safe API.\n")
+	b.writes("// Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and\n")
+	b.writes("// call wuffs_foo__bar__baz methods (which all take a \"this\"-like pointer as\n")
+	b.writes("// their first argument) rather than tweaking bar.private_impl.qux fields.\n")
+	b.writes("//\n")
+	b.writes("// In C, we can just leave wuffs_foo__bar as an incomplete type (unless\n")
+	b.writes("// WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in\n")
+	b.writes("// order to provide convenience methods. These forward on \"this\", so that you\n")
+	b.writes("// can write \"bar->baz(etc)\" instead of \"wuffs_foo__bar__baz(bar, etc)\".\n")
+	b.printf("%s() = delete;\n", fullStructName)
+	b.printf("%s(const %s&) = delete;\n", fullStructName, fullStructName)
+	b.printf("%s& operator=(const %s&) = delete;\n", fullStructName, fullStructName)
+	b.writes("#endif  // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)\n\n")
 
 	// The empty // comment makes clang-format place the function name
 	// at the start of a line.
@@ -998,12 +979,6 @@
 		}
 	}
 
-	b.writes("#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)\n")
-	b.writes("// Disallow copy and assign.\n")
-	b.printf("%s(const %s&) = delete;\n", fullStructName, fullStructName)
-	b.printf("%s& operator=(const %s&) = delete;\n", fullStructName, fullStructName)
-	b.writes("#endif  // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)\n\n")
-
 	b.writes("#endif  // __cplusplus\n\n")
 	return nil
 }
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index ba4572b..866890a 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -2572,26 +2572,12 @@
 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
 
 struct wuffs_base__hasher_u32__struct {
-#ifdef WUFFS_IMPLEMENTATION
-
   struct {
     uint32_t magic;
     uint32_t active_coroutine;
     wuffs_base__vtable first_vtable;
   } private_impl;
 
-#else  // WUFFS_IMPLEMENTATION
-
- private:
-  union {
-    uint32_t align_as_per_magic_field;
-    uint8_t placeholder[1073741824];  // 1 GiB.
-  } private_impl WUFFS_BASE__POTENTIALLY_UNUSED_FIELD;
-
- public:
-
-#endif  // WUFFS_IMPLEMENTATION
-
 #ifdef __cplusplus
 
 #endif  // __cplusplus
@@ -2653,8 +2639,6 @@
 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
 
 struct wuffs_adler32__hasher__struct {
-#ifdef WUFFS_IMPLEMENTATION
-
   // Do not access the private_impl's or private_data's fields directly. There
   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
   // the wuffs_foo__bar__baz functions.
@@ -2672,29 +2656,24 @@
 
   } private_impl;
 
-#else  // WUFFS_IMPLEMENTATION
-
-  // When WUFFS_IMPLEMENTATION is not defined, this placeholder private_impl is
-  // large enough to discourage trying to allocate one on the stack. The sizeof
-  // the real private_impl (and the sizeof the real outermost wuffs_foo__bar
-  // struct) is not part of the public, stable, memory-safe API. Call
-  // wuffs_foo__bar__baz methods (which all take a "this"-like pointer as their
-  // first argument) instead of fiddling with bar.private_impl.qux fields.
-  //
-  // Even when WUFFS_IMPLEMENTATION is not defined, the outermost struct still
-  // defines C++ convenience methods. These methods forward on "this", so that
-  // you can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
- private:
-  union {
-    uint32_t align_as_per_magic_field;
-    uint8_t placeholder[1073741824];  // 1 GiB.
-  } private_impl WUFFS_BASE__POTENTIALLY_UNUSED_FIELD;
-
- public:
-
-#endif  // WUFFS_IMPLEMENTATION
-
 #ifdef __cplusplus
+#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
+  // Disallow constructing or copying an object via standard C++ mechanisms,
+  // e.g. the "new" operator, as this struct is intentionally opaque. Its total
+  // size and field layout is not part of the public, stable, memory-safe API.
+  // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
+  // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
+  // their first argument) rather than tweaking bar.private_impl.qux fields.
+  //
+  // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
+  // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
+  // order to provide convenience methods. These forward on "this", so that you
+  // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
+  wuffs_adler32__hasher__struct() = delete;
+  wuffs_adler32__hasher__struct(const wuffs_adler32__hasher__struct&) = delete;
+  wuffs_adler32__hasher__struct& operator=(
+      const wuffs_adler32__hasher__struct&) = delete;
+#endif  // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
 
   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT  //
   initialize(size_t sizeof_star_self,
@@ -2709,13 +2688,6 @@
     return wuffs_adler32__hasher__update_u32(this, a_x);
   }
 
-#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
-  // Disallow copy and assign.
-  wuffs_adler32__hasher__struct(const wuffs_adler32__hasher__struct&) = delete;
-  wuffs_adler32__hasher__struct& operator=(
-      const wuffs_adler32__hasher__struct&) = delete;
-#endif  // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
-
 #endif  // __cplusplus
 
 };  // struct wuffs_adler32__hasher__struct
@@ -2771,8 +2743,6 @@
 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
 
 struct wuffs_crc32__ieee_hasher__struct {
-#ifdef WUFFS_IMPLEMENTATION
-
   // Do not access the private_impl's or private_data's fields directly. There
   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
   // the wuffs_foo__bar__baz functions.
@@ -2789,29 +2759,25 @@
 
   } private_impl;
 
-#else  // WUFFS_IMPLEMENTATION
-
-  // When WUFFS_IMPLEMENTATION is not defined, this placeholder private_impl is
-  // large enough to discourage trying to allocate one on the stack. The sizeof
-  // the real private_impl (and the sizeof the real outermost wuffs_foo__bar
-  // struct) is not part of the public, stable, memory-safe API. Call
-  // wuffs_foo__bar__baz methods (which all take a "this"-like pointer as their
-  // first argument) instead of fiddling with bar.private_impl.qux fields.
-  //
-  // Even when WUFFS_IMPLEMENTATION is not defined, the outermost struct still
-  // defines C++ convenience methods. These methods forward on "this", so that
-  // you can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
- private:
-  union {
-    uint32_t align_as_per_magic_field;
-    uint8_t placeholder[1073741824];  // 1 GiB.
-  } private_impl WUFFS_BASE__POTENTIALLY_UNUSED_FIELD;
-
- public:
-
-#endif  // WUFFS_IMPLEMENTATION
-
 #ifdef __cplusplus
+#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
+  // Disallow constructing or copying an object via standard C++ mechanisms,
+  // e.g. the "new" operator, as this struct is intentionally opaque. Its total
+  // size and field layout is not part of the public, stable, memory-safe API.
+  // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
+  // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
+  // their first argument) rather than tweaking bar.private_impl.qux fields.
+  //
+  // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
+  // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
+  // order to provide convenience methods. These forward on "this", so that you
+  // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
+  wuffs_crc32__ieee_hasher__struct() = delete;
+  wuffs_crc32__ieee_hasher__struct(const wuffs_crc32__ieee_hasher__struct&) =
+      delete;
+  wuffs_crc32__ieee_hasher__struct& operator=(
+      const wuffs_crc32__ieee_hasher__struct&) = delete;
+#endif  // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
 
   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT  //
   initialize(size_t sizeof_star_self,
@@ -2826,14 +2792,6 @@
     return wuffs_crc32__ieee_hasher__update_u32(this, a_x);
   }
 
-#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
-  // Disallow copy and assign.
-  wuffs_crc32__ieee_hasher__struct(const wuffs_crc32__ieee_hasher__struct&) =
-      delete;
-  wuffs_crc32__ieee_hasher__struct& operator=(
-      const wuffs_crc32__ieee_hasher__struct&) = delete;
-#endif  // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
-
 #endif  // __cplusplus
 
 };  // struct wuffs_crc32__ieee_hasher__struct
@@ -2914,8 +2872,6 @@
 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
 
 struct wuffs_deflate__decoder__struct {
-#ifdef WUFFS_IMPLEMENTATION
-
   // Do not access the private_impl's or private_data's fields directly. There
   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
   // the wuffs_foo__bar__baz functions.
@@ -2982,29 +2938,25 @@
     } s_decode_huffman_slow[1];
   } private_data;
 
-#else  // WUFFS_IMPLEMENTATION
-
-  // When WUFFS_IMPLEMENTATION is not defined, this placeholder private_impl is
-  // large enough to discourage trying to allocate one on the stack. The sizeof
-  // the real private_impl (and the sizeof the real outermost wuffs_foo__bar
-  // struct) is not part of the public, stable, memory-safe API. Call
-  // wuffs_foo__bar__baz methods (which all take a "this"-like pointer as their
-  // first argument) instead of fiddling with bar.private_impl.qux fields.
-  //
-  // Even when WUFFS_IMPLEMENTATION is not defined, the outermost struct still
-  // defines C++ convenience methods. These methods forward on "this", so that
-  // you can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
- private:
-  union {
-    uint32_t align_as_per_magic_field;
-    uint8_t placeholder[1073741824];  // 1 GiB.
-  } private_impl WUFFS_BASE__POTENTIALLY_UNUSED_FIELD;
-
- public:
-
-#endif  // WUFFS_IMPLEMENTATION
-
 #ifdef __cplusplus
+#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
+  // Disallow constructing or copying an object via standard C++ mechanisms,
+  // e.g. the "new" operator, as this struct is intentionally opaque. Its total
+  // size and field layout is not part of the public, stable, memory-safe API.
+  // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
+  // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
+  // their first argument) rather than tweaking bar.private_impl.qux fields.
+  //
+  // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
+  // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
+  // order to provide convenience methods. These forward on "this", so that you
+  // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
+  wuffs_deflate__decoder__struct() = delete;
+  wuffs_deflate__decoder__struct(const wuffs_deflate__decoder__struct&) =
+      delete;
+  wuffs_deflate__decoder__struct& operator=(
+      const wuffs_deflate__decoder__struct&) = delete;
+#endif  // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
 
   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT  //
   initialize(size_t sizeof_star_self,
@@ -3032,14 +2984,6 @@
                                                     a_workbuf);
   }
 
-#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
-  // Disallow copy and assign.
-  wuffs_deflate__decoder__struct(const wuffs_deflate__decoder__struct&) =
-      delete;
-  wuffs_deflate__decoder__struct& operator=(
-      const wuffs_deflate__decoder__struct&) = delete;
-#endif  // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
-
 #endif  // __cplusplus
 
 };  // struct wuffs_deflate__decoder__struct
@@ -3110,8 +3054,6 @@
 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
 
 struct wuffs_lzw__decoder__struct {
-#ifdef WUFFS_IMPLEMENTATION
-
   // Do not access the private_impl's or private_data's fields directly. There
   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
   // the wuffs_foo__bar__baz functions.
@@ -3149,29 +3091,24 @@
 
   } private_data;
 
-#else  // WUFFS_IMPLEMENTATION
-
-  // When WUFFS_IMPLEMENTATION is not defined, this placeholder private_impl is
-  // large enough to discourage trying to allocate one on the stack. The sizeof
-  // the real private_impl (and the sizeof the real outermost wuffs_foo__bar
-  // struct) is not part of the public, stable, memory-safe API. Call
-  // wuffs_foo__bar__baz methods (which all take a "this"-like pointer as their
-  // first argument) instead of fiddling with bar.private_impl.qux fields.
-  //
-  // Even when WUFFS_IMPLEMENTATION is not defined, the outermost struct still
-  // defines C++ convenience methods. These methods forward on "this", so that
-  // you can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
- private:
-  union {
-    uint32_t align_as_per_magic_field;
-    uint8_t placeholder[1073741824];  // 1 GiB.
-  } private_impl WUFFS_BASE__POTENTIALLY_UNUSED_FIELD;
-
- public:
-
-#endif  // WUFFS_IMPLEMENTATION
-
 #ifdef __cplusplus
+#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
+  // Disallow constructing or copying an object via standard C++ mechanisms,
+  // e.g. the "new" operator, as this struct is intentionally opaque. Its total
+  // size and field layout is not part of the public, stable, memory-safe API.
+  // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
+  // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
+  // their first argument) rather than tweaking bar.private_impl.qux fields.
+  //
+  // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
+  // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
+  // order to provide convenience methods. These forward on "this", so that you
+  // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
+  wuffs_lzw__decoder__struct() = delete;
+  wuffs_lzw__decoder__struct(const wuffs_lzw__decoder__struct&) = delete;
+  wuffs_lzw__decoder__struct& operator=(const wuffs_lzw__decoder__struct&) =
+      delete;
+#endif  // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
 
   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT  //
   initialize(size_t sizeof_star_self,
@@ -3203,13 +3140,6 @@
     return wuffs_lzw__decoder__flush(this);
   }
 
-#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
-  // Disallow copy and assign.
-  wuffs_lzw__decoder__struct(const wuffs_lzw__decoder__struct&) = delete;
-  wuffs_lzw__decoder__struct& operator=(const wuffs_lzw__decoder__struct&) =
-      delete;
-#endif  // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
-
 #endif  // __cplusplus
 
 };  // struct wuffs_lzw__decoder__struct
@@ -3343,8 +3273,6 @@
 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
 
 struct wuffs_gif__decoder__struct {
-#ifdef WUFFS_IMPLEMENTATION
-
   // Do not access the private_impl's or private_data's fields directly. There
   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
   // the wuffs_foo__bar__baz functions.
@@ -3473,29 +3401,24 @@
     } s_decode_id_part2[1];
   } private_data;
 
-#else  // WUFFS_IMPLEMENTATION
-
-  // When WUFFS_IMPLEMENTATION is not defined, this placeholder private_impl is
-  // large enough to discourage trying to allocate one on the stack. The sizeof
-  // the real private_impl (and the sizeof the real outermost wuffs_foo__bar
-  // struct) is not part of the public, stable, memory-safe API. Call
-  // wuffs_foo__bar__baz methods (which all take a "this"-like pointer as their
-  // first argument) instead of fiddling with bar.private_impl.qux fields.
-  //
-  // Even when WUFFS_IMPLEMENTATION is not defined, the outermost struct still
-  // defines C++ convenience methods. These methods forward on "this", so that
-  // you can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
- private:
-  union {
-    uint32_t align_as_per_magic_field;
-    uint8_t placeholder[1073741824];  // 1 GiB.
-  } private_impl WUFFS_BASE__POTENTIALLY_UNUSED_FIELD;
-
- public:
-
-#endif  // WUFFS_IMPLEMENTATION
-
 #ifdef __cplusplus
+#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
+  // Disallow constructing or copying an object via standard C++ mechanisms,
+  // e.g. the "new" operator, as this struct is intentionally opaque. Its total
+  // size and field layout is not part of the public, stable, memory-safe API.
+  // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
+  // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
+  // their first argument) rather than tweaking bar.private_impl.qux fields.
+  //
+  // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
+  // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
+  // order to provide convenience methods. These forward on "this", so that you
+  // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
+  wuffs_gif__decoder__struct() = delete;
+  wuffs_gif__decoder__struct(const wuffs_gif__decoder__struct&) = delete;
+  wuffs_gif__decoder__struct& operator=(const wuffs_gif__decoder__struct&) =
+      delete;
+#endif  // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
 
   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT  //
   initialize(size_t sizeof_star_self,
@@ -3581,13 +3504,6 @@
                                             a_opts);
   }
 
-#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
-  // Disallow copy and assign.
-  wuffs_gif__decoder__struct(const wuffs_gif__decoder__struct&) = delete;
-  wuffs_gif__decoder__struct& operator=(const wuffs_gif__decoder__struct&) =
-      delete;
-#endif  // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
-
 #endif  // __cplusplus
 
 };  // struct wuffs_gif__decoder__struct
@@ -3658,8 +3574,6 @@
 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
 
 struct wuffs_gzip__decoder__struct {
-#ifdef WUFFS_IMPLEMENTATION
-
   // Do not access the private_impl's or private_data's fields directly. There
   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
   // the wuffs_foo__bar__baz functions.
@@ -3690,29 +3604,24 @@
     } s_decode_io_writer[1];
   } private_data;
 
-#else  // WUFFS_IMPLEMENTATION
-
-  // When WUFFS_IMPLEMENTATION is not defined, this placeholder private_impl is
-  // large enough to discourage trying to allocate one on the stack. The sizeof
-  // the real private_impl (and the sizeof the real outermost wuffs_foo__bar
-  // struct) is not part of the public, stable, memory-safe API. Call
-  // wuffs_foo__bar__baz methods (which all take a "this"-like pointer as their
-  // first argument) instead of fiddling with bar.private_impl.qux fields.
-  //
-  // Even when WUFFS_IMPLEMENTATION is not defined, the outermost struct still
-  // defines C++ convenience methods. These methods forward on "this", so that
-  // you can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
- private:
-  union {
-    uint32_t align_as_per_magic_field;
-    uint8_t placeholder[1073741824];  // 1 GiB.
-  } private_impl WUFFS_BASE__POTENTIALLY_UNUSED_FIELD;
-
- public:
-
-#endif  // WUFFS_IMPLEMENTATION
-
 #ifdef __cplusplus
+#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
+  // Disallow constructing or copying an object via standard C++ mechanisms,
+  // e.g. the "new" operator, as this struct is intentionally opaque. Its total
+  // size and field layout is not part of the public, stable, memory-safe API.
+  // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
+  // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
+  // their first argument) rather than tweaking bar.private_impl.qux fields.
+  //
+  // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
+  // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
+  // order to provide convenience methods. These forward on "this", so that you
+  // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
+  wuffs_gzip__decoder__struct() = delete;
+  wuffs_gzip__decoder__struct(const wuffs_gzip__decoder__struct&) = delete;
+  wuffs_gzip__decoder__struct& operator=(const wuffs_gzip__decoder__struct&) =
+      delete;
+#endif  // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
 
   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT  //
   initialize(size_t sizeof_star_self,
@@ -3739,13 +3648,6 @@
     return wuffs_gzip__decoder__decode_io_writer(this, a_dst, a_src, a_workbuf);
   }
 
-#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
-  // Disallow copy and assign.
-  wuffs_gzip__decoder__struct(const wuffs_gzip__decoder__struct&) = delete;
-  wuffs_gzip__decoder__struct& operator=(const wuffs_gzip__decoder__struct&) =
-      delete;
-#endif  // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
-
 #endif  // __cplusplus
 
 };  // struct wuffs_gzip__decoder__struct
@@ -3825,8 +3727,6 @@
 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
 
 struct wuffs_zlib__decoder__struct {
-#ifdef WUFFS_IMPLEMENTATION
-
   // Do not access the private_impl's or private_data's fields directly. There
   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
   // the wuffs_foo__bar__baz functions.
@@ -3861,29 +3761,24 @@
     } s_decode_io_writer[1];
   } private_data;
 
-#else  // WUFFS_IMPLEMENTATION
-
-  // When WUFFS_IMPLEMENTATION is not defined, this placeholder private_impl is
-  // large enough to discourage trying to allocate one on the stack. The sizeof
-  // the real private_impl (and the sizeof the real outermost wuffs_foo__bar
-  // struct) is not part of the public, stable, memory-safe API. Call
-  // wuffs_foo__bar__baz methods (which all take a "this"-like pointer as their
-  // first argument) instead of fiddling with bar.private_impl.qux fields.
-  //
-  // Even when WUFFS_IMPLEMENTATION is not defined, the outermost struct still
-  // defines C++ convenience methods. These methods forward on "this", so that
-  // you can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
- private:
-  union {
-    uint32_t align_as_per_magic_field;
-    uint8_t placeholder[1073741824];  // 1 GiB.
-  } private_impl WUFFS_BASE__POTENTIALLY_UNUSED_FIELD;
-
- public:
-
-#endif  // WUFFS_IMPLEMENTATION
-
 #ifdef __cplusplus
+#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
+  // Disallow constructing or copying an object via standard C++ mechanisms,
+  // e.g. the "new" operator, as this struct is intentionally opaque. Its total
+  // size and field layout is not part of the public, stable, memory-safe API.
+  // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
+  // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
+  // their first argument) rather than tweaking bar.private_impl.qux fields.
+  //
+  // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
+  // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
+  // order to provide convenience methods. These forward on "this", so that you
+  // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
+  wuffs_zlib__decoder__struct() = delete;
+  wuffs_zlib__decoder__struct(const wuffs_zlib__decoder__struct&) = delete;
+  wuffs_zlib__decoder__struct& operator=(const wuffs_zlib__decoder__struct&) =
+      delete;
+#endif  // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
 
   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT  //
   initialize(size_t sizeof_star_self,
@@ -3920,13 +3815,6 @@
     return wuffs_zlib__decoder__decode_io_writer(this, a_dst, a_src, a_workbuf);
   }
 
-#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
-  // Disallow copy and assign.
-  wuffs_zlib__decoder__struct(const wuffs_zlib__decoder__struct&) = delete;
-  wuffs_zlib__decoder__struct& operator=(const wuffs_zlib__decoder__struct&) =
-      delete;
-#endif  // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
-
 #endif  // __cplusplus
 
 };  // struct wuffs_zlib__decoder__struct