c++ - Different behaviour between CString operators "+=" and "+" -
while migrating application visualstudio 2005 visualstudio 2015 found different behaviour in code concatenates cstring instances when code built vs2015.
so, i've created simple win32 console application demonstrate problem.
the console application (using mfc shared dll , unicode charachter set) executes simple function:
void f() { cstring x( '\0' ); cstring r( 'a' ); r += x; cstring rr( 'a' ); rr = rr + x; int rsize = r.getlength(); int rrsize = rr.getlength(); assert( rsize == rrsize ); // assert fires when compiled , run // under visual studio 2015! }
it shows that, when cstring containing '\0' char concatenated cstring instance, using '+=' or using '+' leads different results!
when '+=' used size of result calculated counting chars till first '\0'... hence final size 1!
conversely, when operator '+' used result cstring size 2, sum of sizes of concatenated instances!
in visualstudio 2005 result size sum of sizes of concatenated instances!
i filed bug microsoft few weeks ago, until have no answer guys.
my questions:
1. have stumbled onto bug in mcf library??
2. how have worked around bug? thinking ban use of += operator or else replace cstring class custom class, of seems me "a bit" invasive.
the documentation cstringt class contains following cryptic statement:
although possible create cstringt instances contain embedded null characters, recommend against it. calling methods , operators on cstringt objects contain embedded null characters can produce unintended results.
frankly, don't know make of final sentence. take warning careful when embedding null characters. regardless, contractual guarantees should still hold when doing so.
analysis:
this apparently not case cstringt::operator+=, though. in sample code of question implementation of operator+=
invokes the
csimplestringt& operator+=( const csimplestringt& strsrc )
overload, modifies current instance calling
void append( const csimplestringt& strsrc )
which in turn calls
void append( pcxstr pszsrc, int nlength )
passing explicit length argument. should suffice deal c-style strings embedded null characters. oddly enough, implementation starts second-guess input calling stringlengthn(pszsrc, nlength)
(implemented call wcsnlen), re-calculate length of pszsrc. returns 0 cstringt
instance x in sample code.
result:
to me, appears bug in implementation. incidentally, if reverse arguments operator+=
(i.e. x += r;
vs. r += x;
), result string length 2, expected.
resolution:
the clean solution have microsoft acknowledge bug, , provide fix it. wouldn't hold breath, though, microsoft doesn't ship bug fixes, if change behavior of shipped product.
if cannot convince microsoft fix bug, other option not use operator undesired behavior. 1 way use string class. established replacement std::wstring, can convert cstringw
necessary (cstringw cstr(s.c_str(), s.length());
).
update (2016-09-13):
the op filed defect report microsoft, , acknowledged bug. bug fix implemented, "it won't appear until next major version of libraries (which may not ship in current [2016-03-31] visual studio vnext)".
Comments
Post a Comment