https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84667
Jonathan Wakely <redi at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|WAITING |RESOLVED Resolution|--- |INVALID --- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> --- OK I've finished debugging this horribly obfuscated program, and this is not a compiler bug. This is copy-initialization: estrbuf copybuf1 = varbuf4.as_const(); That means it's equivalent to this: estrbuf copybuf1 = estrbuf(varbuf4.as_const()); This constructs a temporary strbuf which has the expected value (0x80000000) but then tries to copy-construct another estrbuf. Your copy constructor cannot be used to copy temporaries, because you declared it so it only works for lvalues: inline xstrbuf( xstrbuf& s ) so instead the temporary gets converted to its base class (via slicing) and calls this constructor: inline xstrbuf( base_str s ) and that constructor sets bufParams to: bufParams = s.length | xstrbuf_bufUserAllocatedBit; Which explains the unwanted 0xb in the value 8000000b, it comes from s.length In the second case you use direct-initialization: estrbuf copybuf2( varbuf4.as_const() ); so there is no temporary, no slicing, and no copy that gets s.length in the params. You should fix your copy constructor to accept const-lvalues, and avoid slicing, (and stop misusing the pure attribute, and remove the useless register keywords, and use more whitespace to help readability, and stop using so many macros, ...)