c++ - versiones - Comprendiendo_GLIBCXX_USE_CXX11_ABI de GCC 5 o la nueva ABI
gcc versiones (2)
El antiguo
std::string
no era compatible con C ++ 11 porque ese estándar prohíbe una implementación de copia en escritura. No había forma de crear unastd::string
sin romper ABI, por lo que lo hicieron con una forma de volver a la versión no compatible para la compatibilidad ABI.Sí.
Asegúrate de que todas las unidades de traducción de tu programa utilicen el mismo valor de
_GLIBCXX_USE_CXX11_ABI
y estarás bien. Si los mezcla en unidades de traducción definitivamente tendrá problemas. Podría estar bien si tiene diferentes valores de la definición en diferentes unidades de traducción que no comunican lasstring
s entre sí.
https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html
Me encontré con problemas de bloqueo / valgrind al usar std :: string en GCC 5. El enlace anterior sugiere que hay un cambio en el ABI que inicia GCC 5.x. El nuevo ABI predeterminado para libstd ++ es C ++ 11/14 ... que no es compatible con el ABI anterior. Hay una manera de seleccionar el ABI más antiguo utilizando una definición.
Estoy tratando de entender cuál es la diferencia entre las ABI y no he encontrado detalles. Me gustaría ayudar a entender:
- ¿Qué tipo de problemas con std :: string deben solucionarse para ser compatibles con el nuevo ABI? ¿Están relacionados con la copia en escritura?
- ¿Los cambios lo romperán para ABI más viejo?
- ¿Algún consejo para hacer que _GLIBCXX_USE_CXX11_ABI funcione?
Más detalles sobre el problema que encontré ( https://github.com/YasserAsmi/jvar/issues/21 ) El proyecto funcionó bien en GCC 4.8 y Clang. Con GCC, el mismo código se niega a ejecutar:
x_misc(33112,0x7fff728c2000) malloc: *** error for object 0x7fd639c034cc: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
Y aquí hay una salida parcial de Valgrind:
==33027== Invalid read of size 1
==33027== at 0x1006F78BA: _platform_memmove$VARIANT$Nehalem (in /usr/lib/system/libsystem_platform.dylib)
==33027== by 0x100009388: jvar::Variant::toString[abi:cxx11]() const (in bin/ex_misc)
==33027== by 0x1000023A7: bugreport() (in bin/ex_misc)
==33027== by 0x1000133B8: main (in bin/ex_misc)
El proyecto usa std :: string y tiene alguna administración de memoria personalizada. Está haciendo algunas operaciones no típicas pero válidas usando constructores de ubicación, etc. Estoy tratando de entender mejor qué tipo de código afecta la API y cómo solucionarlo, un lugar para comenzar.
Hay una diferencia interesante entre las cadenas COW y no-COW, por ejemplo:
std::string some_string;
std::string foo()
{
return some_string;
}
char const *s = foo().c_str();
printf("%s/n",s);
Esto funcionaría con las cadenas COW como c_str () que son devueltas por some_string y foo point a la misma memoria, pero cuando no es COW, s se invalidará una vez que se destruya std :: string devuelta por foo
.
Desde la muestra hay que mirar en esta dirección.