Al usar el mismo código, simplemente cambiando el compilador (de un compilador de C a un compilador de C++) cambiará la cantidad de memoria asignada. No estoy muy seguro de por qué es esto y me gustaría entenderlo más. Hasta ahora, la mejor respuesta que he recibido es "probablemente los flujos de E/S", que no es muy descriptivo y me hace preguntarme sobre el aspecto de "no pagas por lo que no usas" de C++.
Estoy usando los compiladores Clang y GCC, versiones 7.0.1-8 y 8.3.0-6 respectivamente. Mi sistema se ejecuta en Debian 10 (Buster), la última. Los puntos de referencia se realizan a través de Valgrind Massif.
#include <stdio.h> int main() { printf("Hello, world!\n"); return 0; }El código utilizado no cambia, pero ya sea que compile como C o como C++, cambia los resultados del benchmark de Valgrind. Sin embargo, los valores siguen siendo coherentes entre los compiladores. Las asignaciones de tiempo de ejecución (pico) para el programa son las siguientes:
Para compilar, uso los siguientes comandos:
clang -O3 -o c-clang ./main.c gcc -O3 -o c-gcc ./main.c clang++ -O3 -o cpp-clang ./main.cpp g++ -O3 -o cpp-gcc ./main.cpp Para Valgrind, ejecuto valgrind --tool=massif --massif-out-file=m_compiler_lang ./compiler-lang en cada compilador e idioma, luego ms_print para mostrar los picos.
¿Estoy haciendo algo mal aquí?
El uso del montón proviene de la biblioteca estándar de C++. Asigna memoria para el uso de la biblioteca interna en el inicio. Si no vincula contra él, no debería haber ninguna diferencia entre la versión C y C++. Con GCC y Clang, puede compilar el archivo con:
g++ -Wl,--según sea necesario main.cpp
Esto le indicará al enlazador que no enlace contra bibliotecas no utilizadas. En su código de ejemplo, la biblioteca de C++ no se usa, por lo que no debe vincularse con la biblioteca estándar de C++.
También puede probar esto con el archivo C. Si compilas con:
gcc principal.c -lstdc++
El uso del montón volverá a aparecer, aunque haya creado un programa en C.
El uso del montón obviamente depende de la implementación específica de la biblioteca de C++ que esté utilizando. En su caso, esa es la biblioteca GNU C++, libstdc++ . Es posible que otras implementaciones no asignen la misma cantidad de memoria, o que no asignen memoria en absoluto (al menos no en el inicio). La biblioteca LLVM C++ ( libc++ ), por ejemplo, no realiza la asignación de almacenamiento dinámico en el inicio, al menos en mi Linux máquina:
clang++ -stdlib=libc++ principal.cpp
El uso del montón es lo mismo que no vincular en absoluto contra él.
(Si la compilación falla, es probable que libc++ no esté instalado. El nombre del paquete suele contener "libc++" o "libcxx").
Ni GCC ni Clang son compiladores, en realidad son programas de controlador de cadenas de herramientas. Eso significa que invocan al compilador, al ensamblador y al enlazador.
Si compila su código con un compilador C o C ++, obtendrá el mismo ensamblaje producido. El Ensamblador producirá los mismos objetos. La diferencia es que el controlador de la cadena de herramientas proporcionará una entrada diferente al enlazador para los dos lenguajes diferentes: diferentes inicios (C++ requiere código para ejecutar constructores y destructores para objetos con duración de almacenamiento local de subprocesos o estático a nivel de espacio de nombres, y requiere infraestructura para la pila marcos para admitir el desenrollado durante el procesamiento de excepciones, por ejemplo), la biblioteca estándar de C++ (que también tiene objetos de duración de almacenamiento estático a nivel de espacio de nombres) y probablemente bibliotecas de tiempo de ejecución adicionales (por ejemplo, libgcc con su infraestructura de desenrollado de pilas).
En resumen, no es el compilador el que causa el aumento de la huella, es la vinculación de las cosas que ha elegido usar al elegir el lenguaje C++.
Es cierto que C++ tiene la filosofía de "pagar solo por lo que usa", pero al usar el lenguaje, paga por ello. Puede deshabilitar partes del lenguaje (RTTI, manejo de excepciones) pero ya no usará C++. Como se menciona en otra respuesta, si no usa la biblioteca estándar en absoluto, puede indicarle al controlador que lo deje fuera (--Wl,--según sea necesario) pero si no va a usar ninguna de las funciones de C++ o su biblioteca, ¿por qué eligen C++ como lenguaje de programación?