significa que postincremento hay entre diferencia c++ visual-studio visual-c++ mfc visual-studio-2015

c++ - que - postincremento java



Comportamiento diferente entre los operadores de CString "+=" y "+" (1)

La documentación de la clase CStringT contiene la siguiente declaración críptica:

Aunque es posible crear instancias de CStringT que contengan caracteres nulos incorporados, recomendamos que no lo haga. Los métodos y operadores de llamada en objetos CStringT que contienen caracteres nulos incorporados pueden producir resultados no deseados.

Francamente, realmente no sé qué hacer con la oración final. Lo tomo como una advertencia para tener cuidado al incrustar caracteres nulos. De todos modos, las garantías contractuales deberían mantenerse al hacerlo.

Análisis:

Este aparentemente no es el caso con CStringT :: operator + = , though. En el código de ejemplo de la pregunta, la implementación del operator+= invoca el

CSimpleStringT& operator+=( const CSimpleStringT& strSrc )

sobrecarga, que modifica la instancia actual llamando

void Append( const CSimpleStringT& strSrc )

que a su vez llama

void Append( PCXSTR pszSrc, int nLength )

pasando un argumento de longitud explícita. Esto debería ser suficiente para tratar cadenas de estilo C con caracteres nulos incorporados. Por extraño que parezca, la implementación comienza a adivinar la entrada llamando a StringLengthN(pszSrc, nLength) (implementado como una llamada a wcsnlen ), para volver a calcular la longitud de pszSrc . Esto devuelve 0 para la instancia CStringT x en el código de muestra.

Resultado:

Para mí, esto parece ser un error en la implementación. Por cierto, si revierte los argumentos al operator+= (es decir, x += r; vs. r += x; ), el resultado es una cadena con longitud 2, como se esperaba.

Resolución:

La única solución limpia sería que Microsoft reconozca el error y proporcione una solución. Sin embargo, no aguantaría la respiración, ya que Microsoft generalmente no envía correcciones de errores, si cambian el comportamiento de un producto enviado.

Si no puede convencer a Microsoft para que corrija ese error, su única otra opción es no utilizar el operador con un comportamiento no deseado. Una forma sería usar otra clase de cadena. Un reemplazo bien establecido es std :: wstring , que puede convertir a un CStringW cuando sea necesario ( CStringW cstr(s.c_str(), s.length()); ).

Actualización (2016-09-13):

El OP archivó un informe de defectos con Microsoft, y reconocieron el error. Se implementó una corrección de errores, pero "no aparecerá hasta la próxima versión principal de las bibliotecas (que puede no enviarse necesariamente en la versión actual [2016-03-31] Visual Studio vNext)" .

Al migrar una aplicación de VisualStudio 2005 a VisualStudio 2015, encontramos un comportamiento diferente en algunos códigos que concatena instancias de CString cuando ese código se genera con VS2015.
Por lo tanto, he creado una aplicación de consola Win32 simple para demostrar el problema.

La aplicación de consola (que usa MFC como dll compartido y conjunto de caracteres Unicode) ejecuta esta sencilla función:

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 ); // This assert fires when compiled and run // under Visual Studio 2015! }

Muestra que, cuando un CString que contiene un char ''/ 0'' se concatena a otra instancia de CString, usar ''+ ='' o usar ''+'' conduce a resultados diferentes.

Cuando se usa ''+ ='', el tamaño del resultado se calcula contando todos los caracteres hasta el primer ''/ 0'' ... ¡por lo tanto, el tamaño final es 1!
Por el contrario, cuando se usa el operador ''+'', el tamaño del resultado CString es 2, ¡esa es la suma de los tamaños de las instancias concatenadas!

En VisualStudio 2005, el tamaño del resultado es siempre la suma de los tamaños de las instancias concatenadas.

Archivé un error a Microsoft hace unas semanas, pero hasta ahora no tengo respuesta de esos tipos.

Mis preguntas:
1. ¿Alguien ha encontrado este error en la biblioteca de MCF?
2. ¿Cómo has trabajado con este error? Estamos pensando en prohibir el uso del operador + = o si no reemplazamos la clase CString por una clase personalizada, pero todo esto me parece "un poco" invasivo.