ensure xer encode yields the same number of bytes as it sends to the callback
diff --git a/skeletons/BIT_STRING.c b/skeletons/BIT_STRING.c
index dcaeac3..a68621a 100644
--- a/skeletons/BIT_STRING.c
+++ b/skeletons/BIT_STRING.c
@@ -117,7 +117,6 @@
 		int v = *buf;
 		int nline = xcan?0:(((buf - st->buf) % 8) == 0);
 		if(p >= scend || nline) {
-			er.encoded += p - scratch;
 			ASN__CALLBACK(scratch, p - scratch);
 			p = scratch;
 			if(nline) ASN__TEXT_INDENT(1, ilevel);
@@ -129,7 +128,6 @@
 
 	if(!xcan && ((buf - st->buf) % 8) == 0)
 		ASN__TEXT_INDENT(1, ilevel);
-	er.encoded += p - scratch;
 	ASN__CALLBACK(scratch, p - scratch);
 	p = scratch;
 
@@ -139,7 +137,6 @@
 		int i;
 		for(i = 7; i >= ubits; i--)
 			*p++ = (v & (1 << i)) ? 0x31 : 0x30;
-		er.encoded += p - scratch;
 		ASN__CALLBACK(scratch, p - scratch);
 	}
 
diff --git a/skeletons/BOOLEAN.c b/skeletons/BOOLEAN.c
index 7161698..21a858c 100644
--- a/skeletons/BOOLEAN.c
+++ b/skeletons/BOOLEAN.c
@@ -198,7 +198,7 @@
 	int ilevel, enum xer_encoder_flags_e flags,
 		asn_app_consume_bytes_f *cb, void *app_key) {
 	const BOOLEAN_t *st = (const BOOLEAN_t *)sptr;
-	asn_enc_rval_t er;
+	asn_enc_rval_t er = {0, 0, 0};
 
 	(void)ilevel;
 	(void)flags;
@@ -207,10 +207,8 @@
 
 	if(*st) {
 		ASN__CALLBACK("<true/>", 7);
-		er.encoded = 7;
 	} else {
 		ASN__CALLBACK("<false/>", 8);
-		er.encoded = 8;
 	}
 
 	ASN__ENCODED_OK(er);
diff --git a/skeletons/OCTET_STRING.c b/skeletons/OCTET_STRING.c
index ac486ec..2f2efc4 100644
--- a/skeletons/OCTET_STRING.c
+++ b/skeletons/OCTET_STRING.c
@@ -578,7 +578,6 @@
 		uint8_t b = st->bits_unused & 0x07;
 		if(b && st->size) fix_last_byte = 1;
 		ASN__CALLBACK(&b, 1);
-		er.encoded++;
 	}
 
 	/* Invoke callback for the main part of the buffer */
@@ -590,7 +589,6 @@
 		ASN__CALLBACK(&b, 1);
 	}
 
-	er.encoded += st->size;
 	ASN__ENCODED_OK(er);
 cb_failed:
 	ASN__ENCODE_FAILED;
@@ -624,7 +622,6 @@
 		for(; buf < end; buf++) {
 			if(p >= scend) {
 				ASN__CALLBACK(scratch, p - scratch);
-				er.encoded += p - scratch;
 				p = scratch;
 			}
 			*p++ = h2c[(*buf >> 4) & 0x0F];
@@ -632,12 +629,10 @@
 		}
 
 		ASN__CALLBACK(scratch, p-scratch);	/* Dump the rest */
-		er.encoded += p - scratch;
 	} else {
 		for(i = 0; buf < end; buf++, i++) {
 			if(!(i % 16) && (i || st->size > 16)) {
 				ASN__CALLBACK(scratch, p-scratch);
-				er.encoded += (p-scratch);
 				p = scratch;
 				ASN__TEXT_INDENT(1, ilevel);
 			}
@@ -648,7 +643,6 @@
 		if(p - scratch) {
 			p--;	/* Remove the tail space */
 			ASN__CALLBACK(scratch, p-scratch); /* Dump the rest */
-			er.encoded += p - scratch;
 			if(st->size > 16)
 				ASN__TEXT_INDENT(1, ilevel-1);
 		}
diff --git a/skeletons/asn_internal.h b/skeletons/asn_internal.h
index 3479736..758b7b6 100644
--- a/skeletons/asn_internal.h
+++ b/skeletons/asn_internal.h
@@ -70,28 +70,29 @@
 /*
  * Invoke the application-supplied callback and fail, if something is wrong.
  */
-#define	ASN__E_cbc(buf, size)	(cb((buf), (size), app_key) < 0)
-#define	ASN__E_CALLBACK(foo)	do {					\
-		if(foo)	goto cb_failed;					\
-	} while(0)
-#define	ASN__CALLBACK(buf, size)					\
-	ASN__E_CALLBACK(ASN__E_cbc(buf, size))
-#define	ASN__CALLBACK2(buf1, size1, buf2, size2)			\
-	ASN__E_CALLBACK(ASN__E_cbc(buf1, size1) || ASN__E_cbc(buf2, size2))
-#define	ASN__CALLBACK3(buf1, size1, buf2, size2, buf3, size3)		\
-	ASN__E_CALLBACK(ASN__E_cbc(buf1, size1)			\
-		|| ASN__E_cbc(buf2, size2)				\
-		|| ASN__E_cbc(buf3, size3))
+#define ASN__E_cbc(buf, size) (cb((buf), (size), app_key) < 0)
+#define ASN__E_CALLBACK(size, foo) \
+    do {                           \
+        if(foo) goto cb_failed;    \
+        er.encoded += (size);      \
+    } while(0)
+#define ASN__CALLBACK(buf, size) ASN__E_CALLBACK(size, ASN__E_cbc(buf, size))
+#define ASN__CALLBACK2(buf1, size1, buf2, size2) \
+    ASN__E_CALLBACK((size1) + (size2),           \
+                    ASN__E_cbc(buf1, size1) || ASN__E_cbc(buf2, size2))
+#define ASN__CALLBACK3(buf1, size1, buf2, size2, buf3, size3)          \
+    ASN__E_CALLBACK((size1) + (size2) + (size3),                       \
+                    ASN__E_cbc(buf1, size1) || ASN__E_cbc(buf2, size2) \
+                        || ASN__E_cbc(buf3, size3))
 
-#define	ASN__TEXT_INDENT(nl, level) do {            \
-        int tmp_level = (level);                    \
-        int tmp_nl = ((nl) != 0);                   \
-        int tmp_i;                                  \
-        if(tmp_nl) ASN__CALLBACK("\n", 1);          \
-        if(tmp_level < 0) tmp_level = 0;            \
-        for(tmp_i = 0; tmp_i < tmp_level; tmp_i++)  \
-            ASN__CALLBACK("    ", 4);               \
-        er.encoded += tmp_nl + 4 * tmp_level;       \
+#define ASN__TEXT_INDENT(nl, level)                                          \
+    do {                                                                     \
+        int tmp_level = (level);                                             \
+        int tmp_nl = ((nl) != 0);                                            \
+        int tmp_i;                                                           \
+        if(tmp_nl) ASN__CALLBACK("\n", 1);                                   \
+        if(tmp_level < 0) tmp_level = 0;                                     \
+        for(tmp_i = 0; tmp_i < tmp_level; tmp_i++) ASN__CALLBACK("    ", 4); \
     } while(0)
 
 #define	_i_INDENT(nl)	do {                        \
diff --git a/skeletons/constr_CHOICE.c b/skeletons/constr_CHOICE.c
index ed5cebe..4ecb220 100644
--- a/skeletons/constr_CHOICE.c
+++ b/skeletons/constr_CHOICE.c
@@ -810,16 +810,15 @@
 
 		er.encoded = 0;
 
-                if(!(flags & XER_F_CANONICAL)) ASN__TEXT_INDENT(1, ilevel);
+		if(!(flags & XER_F_CANONICAL)) ASN__TEXT_INDENT(1, ilevel);
 		ASN__CALLBACK3("<", 1, mname, mlen, ">", 1);
 
 		tmper = elm->type->op->xer_encoder(elm->type, memb_ptr,
 				ilevel + 1, flags, cb, app_key);
 		if(tmper.encoded == -1) return tmper;
+		er.encoded += tmper.encoded;
 
 		ASN__CALLBACK3("</", 2, mname, mlen, ">", 1);
-
-		er.encoded += 5 + (2 * mlen) + tmper.encoded;
 	}
 
 	if(!(flags & XER_F_CANONICAL)) ASN__TEXT_INDENT(1, ilevel - 1);
diff --git a/skeletons/constr_SEQUENCE.c b/skeletons/constr_SEQUENCE.c
index 3caf5d2..4ba4b08 100644
--- a/skeletons/constr_SEQUENCE.c
+++ b/skeletons/constr_SEQUENCE.c
@@ -929,9 +929,9 @@
             tmp_def_val = 0;
         }
         if(tmper.encoded == -1) return tmper;
+        er.encoded += tmper.encoded;
 
         ASN__CALLBACK3("</", 2, mname, mlen, ">", 1);
-        er.encoded += 5 + (2 * mlen) + tmper.encoded;
     }
 
     if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1);
diff --git a/skeletons/constr_SEQUENCE_OF.c b/skeletons/constr_SEQUENCE_OF.c
index 3b9c1f5..a8e20ec 100644
--- a/skeletons/constr_SEQUENCE_OF.c
+++ b/skeletons/constr_SEQUENCE_OF.c
@@ -88,56 +88,55 @@
 }
 
 asn_enc_rval_t
-SEQUENCE_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
-	int ilevel, enum xer_encoder_flags_e flags,
-		asn_app_consume_bytes_f *cb, void *app_key) {
-	asn_enc_rval_t er;
-        asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics;
-	asn_TYPE_member_t *elm = td->elements;
-	asn_anonymous_sequence_ *list = _A_SEQUENCE_FROM_VOID(sptr);
-	const char *mname = specs->as_XMLValueList
-		? 0 : ((*elm->name) ? elm->name : elm->type->xml_tag);
-	unsigned int mlen = mname ? strlen(mname) : 0;
-	int xcan = (flags & XER_F_CANONICAL);
-	int i;
+SEQUENCE_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, int ilevel,
+                       enum xer_encoder_flags_e flags,
+                       asn_app_consume_bytes_f *cb, void *app_key) {
+    asn_enc_rval_t er;
+    asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics;
+    asn_TYPE_member_t *elm = td->elements;
+    asn_anonymous_sequence_ *list = _A_SEQUENCE_FROM_VOID(sptr);
+    const char *mname = specs->as_XMLValueList
+                            ? 0
+                            : ((*elm->name) ? elm->name : elm->type->xml_tag);
+    unsigned int mlen = mname ? strlen(mname) : 0;
+    int xcan = (flags & XER_F_CANONICAL);
+    int i;
 
-	if(!sptr) ASN__ENCODE_FAILED;
+    if(!sptr) ASN__ENCODE_FAILED;
 
-	er.encoded = 0;
+    er.encoded = 0;
 
-	for(i = 0; i < list->count; i++) {
-		asn_enc_rval_t tmper;
-		void *memb_ptr = list->array[i];
-		if(!memb_ptr) continue;
+    for(i = 0; i < list->count; i++) {
+        asn_enc_rval_t tmper;
+        void *memb_ptr = list->array[i];
+        if(!memb_ptr) continue;
 
-		if(mname) {
-			if(!xcan) ASN__TEXT_INDENT(1, ilevel);
-			ASN__CALLBACK3("<", 1, mname, mlen, ">", 1);
-		}
+        if(mname) {
+            if(!xcan) ASN__TEXT_INDENT(1, ilevel);
+            ASN__CALLBACK3("<", 1, mname, mlen, ">", 1);
+        }
 
-		tmper = elm->type->op->xer_encoder(elm->type, memb_ptr,
-				ilevel + 1, flags, cb, app_key);
-		if(tmper.encoded == -1) return tmper;
-                if(tmper.encoded == 0 && specs->as_XMLValueList) {
-                        const char *name = elm->type->xml_tag;
-			size_t len = strlen(name);
-			if(!xcan) ASN__TEXT_INDENT(1, ilevel + 1);
-			ASN__CALLBACK3("<", 1, name, len, "/>", 2);
-                }
+        tmper = elm->type->op->xer_encoder(elm->type, memb_ptr, ilevel + 1,
+                                           flags, cb, app_key);
+        if(tmper.encoded == -1) return tmper;
+        er.encoded += tmper.encoded;
+        if(tmper.encoded == 0 && specs->as_XMLValueList) {
+            const char *name = elm->type->xml_tag;
+            size_t len = strlen(name);
+            if(!xcan) ASN__TEXT_INDENT(1, ilevel + 1);
+            ASN__CALLBACK3("<", 1, name, len, "/>", 2);
+        }
 
-		if(mname) {
-			ASN__CALLBACK3("</", 2, mname, mlen, ">", 1);
-			er.encoded += 5;
-		}
+        if(mname) {
+            ASN__CALLBACK3("</", 2, mname, mlen, ">", 1);
+        }
+    }
 
-		er.encoded += (2 * mlen) + tmper.encoded;
-	}
+    if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1);
 
-	if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1);
-
-	ASN__ENCODED_OK(er);
+    ASN__ENCODED_OK(er);
 cb_failed:
-	ASN__ENCODE_FAILED;
+    ASN__ENCODE_FAILED;
 }
 
 asn_enc_rval_t
diff --git a/skeletons/constr_SET.c b/skeletons/constr_SET.c
index deff98f..70fb271 100644
--- a/skeletons/constr_SET.c
+++ b/skeletons/constr_SET.c
@@ -869,10 +869,9 @@
 		tmper = elm->type->op->xer_encoder(elm->type, memb_ptr,
 				ilevel + 1, flags, cb, app_key);
 		if(tmper.encoded == -1) return tmper;
+		er.encoded += tmper.encoded;
 
 		ASN__CALLBACK3("</", 2, mname, mlen, ">", 1);
-
-		er.encoded += 5 + (2 * mlen) + tmper.encoded;
 	}
 
 	if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1);
diff --git a/skeletons/constr_SET_OF.c b/skeletons/constr_SET_OF.c
index 48f754d..ba61496 100644
--- a/skeletons/constr_SET_OF.c
+++ b/skeletons/constr_SET_OF.c
@@ -700,11 +700,8 @@
 		tmper = elm->type->op->xer_encoder(elm->type, memb_ptr,
 				ilevel + (specs->as_XMLValueList != 2),
 				flags, cb, app_key);
-		if(tmper.encoded == -1) {
-			td = tmper.failed_type;
-			sptr = tmper.structure_ptr;
-			goto cb_failed;
-		}
+		if(tmper.encoded == -1) return tmper;
+		er.encoded += tmper.encoded;
 		if(tmper.encoded == 0 && specs->as_XMLValueList) {
 			const char *name = elm->type->xml_tag;
 			size_t len = strlen(name);
@@ -713,10 +710,8 @@
 
 		if(mname) {
 			ASN__CALLBACK3("</", 2, mname, mlen, ">", 1);
-			er.encoded += 5;
 		}
 
-		er.encoded += (2 * mlen) + tmper.encoded;
 	}
 
 	if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1);
@@ -726,6 +721,7 @@
 		xer_tmp_enc_t *end = encs + encs_count;
 		ssize_t control_size = 0;
 
+		er.encoded = 0;
 		cb = original_cb;
 		app_key = original_app_key;
 		qsort(encs, encs_count, sizeof(encs[0]), SET_OF_xer_order);
@@ -741,9 +737,7 @@
 
 	goto cleanup;
 cb_failed:
-	er.encoded = -1;
-	er.failed_type = td;
-	er.structure_ptr = sptr;
+	ASN__ENCODE_FAILED;
 cleanup:
 	if(encs) {
 		size_t n;
diff --git a/skeletons/xer_encoder.c b/skeletons/xer_encoder.c
index 25b3bfa..c50ffa3 100644
--- a/skeletons/xer_encoder.c
+++ b/skeletons/xer_encoder.c
@@ -13,7 +13,8 @@
 xer_encode(asn_TYPE_descriptor_t *td, void *sptr,
 	enum xer_encoder_flags_e xer_flags,
 		asn_app_consume_bytes_f *cb, void *app_key) {
-	asn_enc_rval_t er, tmper;
+	asn_enc_rval_t er = {0, 0, 0};
+	asn_enc_rval_t tmper;
 	const char *mname;
 	size_t mlen;
 	int xcan = (xer_flags & XER_F_CANONICAL) ? 1 : 2;
@@ -27,11 +28,10 @@
 
 	tmper = td->op->xer_encoder(td, sptr, 1, xer_flags, cb, app_key);
 	if(tmper.encoded == -1) return tmper;
+	er.encoded += tmper.encoded;
 
 	ASN__CALLBACK3("</", 2, mname, mlen, ">\n", xcan);
 
-	er.encoded = 4 + xcan + (2 * mlen) + tmper.encoded;
-
 	ASN__ENCODED_OK(er);
 cb_failed:
 	ASN__ENCODE_FAILED;
diff --git a/tests/tests-c-compiler/check-src/check-70.-fwide-types.c b/tests/tests-c-compiler/check-src/check-70.-fwide-types.c
index 0000241..5e450b6 100644
--- a/tests/tests-c-compiler/check-src/check-70.-fwide-types.c
+++ b/tests/tests-c-compiler/check-src/check-70.-fwide-types.c
@@ -74,7 +74,7 @@
 
     fprintf(stderr, "SAVED OBJECT IN SIZE %d/%zd\n", buf_offset, rval.encoded);
 
-    // assert(buf_offset == rval.encoded);
+    assert(buf_offset == rval.encoded);
 }
 
 static PDU_t *
diff --git a/tests/tests-c-compiler/check-src/check-70.c b/tests/tests-c-compiler/check-src/check-70.c
index f5527cb..16e3e2e 100644
--- a/tests/tests-c-compiler/check-src/check-70.c
+++ b/tests/tests-c-compiler/check-src/check-70.c
@@ -66,9 +66,9 @@
 		return;
     }
 
-    fprintf(stderr, "SAVED OBJECT IN SIZE %d\n", buf_offset);
+    fprintf(stderr, "SAVED OBJECT IN SIZE %d/%zu\n", buf_offset, rval.encoded);
 
-    // assert(buf_offset == rval.encoded);
+    assert(buf_offset == rval.encoded);
 }
 
 static PDU_t *