Почему начальное распределение C++ намного больше, чем C?

При использовании того же кода простое изменение компилятора (с компилятора C на компилятор C++) изменит объем выделенной памяти. Я не совсем уверен, почему это так и хотел бы понять это больше. Пока что лучший ответ, который я получил, это "вероятно, потоки ввода/вывода", который не очень описательный и заставляет меня задуматься о аспекте "вы не платите за то, что вы не используете" C++,

Я использую компиляторы Clang и GCC, версии 7.0.1-8 и 8.3.0-6 соответственно. Моя система работает на Debian 10 (Buster), последняя версия. Тесты выполняются через массив Valgrind.

#include <stdio.h>

int main() {
    printf("Hello, world!\n");
    return 0;
}

Используемый код не изменяется, но, независимо от того, скомпилирован ли я как C или как C++, он изменяет результаты теста Valgrind. Однако значения остаются неизменными для разных компиляторов. Распределение времени выполнения (пик) для программы происходит следующим образом:

  • GCC (C): 1032 байта (1 КБ)
  • G++ (C++): 73 744 байта (~ 74 КБ)
  • Clang (C): 1032 байта (1 КБ)
  • Клан G++ (C++): 73 744 байта (~ 74 КБ)

Для компиляции я использую следующие команды:

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

Для Valgrind я запускаю valgrind --tool=massif --massif-out-file=m_compiler_lang./compiler-lang для каждого компилятора и языка, а затем ms_print для отображения пиков.

Я что-то здесь не так делаю?

Ответ 1

Использование кучи происходит из стандартной библиотеки C++. Он выделяет память для внутреннего использования библиотеки при запуске. Если вы не ссылаетесь на него, между версиями C и C++ не должно быть нулевой разницы. С GCC и Clang вы можете скомпилировать файл с:

g++ -Wl,--as-needed main.cpp

Это даст указание компоновщику не связываться с неиспользуемыми библиотеками. В вашем примере кода библиотека C++ не используется, поэтому она не должна ссылаться на стандартную библиотеку C++.

Вы также можете проверить это с помощью файла C. Если вы компилируете с:

gcc main.c -lstdc++

Использование кучи появится снова, даже если вы создали программу на Си.

Использование кучи, очевидно, зависит от конкретной используемой вами реализации библиотеки C++. В вашем случае это библиотека GNU C++, libstd C++. Другие реализации могут не выделять такой же объем памяти или вообще не выделять какую-либо память (по крайней мере, при запуске). Библиотека LLVM C++ (lib C++), например, не выполняет выделение кучи при запуске, по крайней мере, на моей машине Linux:

clang++ -stdlib=libc++ main.cpp

Использование кучи - это то же самое, что вообще не связываться с ним.

(Если компиляция не удалась, возможно, lib C++ не установлен. Имя пакета обычно содержит "lib C++" или "libcxx".)

Ответ 2

Ни GCC, ни Clang не являются компиляторами - они на самом деле программы-драйверы инструментов. Это означает, что они вызывают компилятор, ассемблер и компоновщик.

Если вы скомпилируете свой код с помощью компилятора C или C++, вы получите ту же сборку. Ассемблер будет производить те же объекты. Разница заключается в том, что драйвер цепочки инструментов будет обеспечивать разные входные данные для компоновщика для двух разных языков: разные стартапы (C++ требует код для выполнения конструкторов и деструкторов для объектов со статическим или локальным потоком хранилища на уровне пространства имен и требует инфраструктуры например, для стековых фреймов для поддержки разматывания во время обработки исключений), стандартной библиотеки C++ (которая также имеет объекты статической длительности хранения на уровне пространства имен) и, возможно, дополнительных библиотек времени выполнения (например, libgcc с его инфраструктурой разматывания стека).).

Короче говоря, это не компилятор, вызывающий увеличение занимаемой площади, а связывание материалов, которые вы выбрали, выбрав язык C++.

Это правда, что C++ имеет философию "плати только за то, что ты используешь", но используя язык, ты платишь за это. Вы можете отключить части языка (RTTI, обработка исключений), но тогда вы больше не используете C++. Как упомянуто в другом ответе, если вы вообще не используете стандартную библиотеку, вы можете дать указание драйверу опустить это (--Wl, - по мере необходимости), но если вы не собираетесь использовать какие-либо функции C++ или его библиотеки, почему вы даже выбираете C++ в качестве языка программирования?

Ответ 3

c++ - мерзость. питон новый король!