Подтвердить что ты не робот

Что требует программа на С++?

Этот вопрос беспокоил меня какое-то время. Рассмотрим две следующие программы:

#incude <iostream>
int main()
{
   std::cout << "Hello, World!";
}

и

int main()
{
   int x = 5;
   int y = x*x;
}
  • Окна: Первый пример, естественно, требует наличия некоторой системы .dll для консоли. Я это понимаю. А как насчет второго? Нужно ли что-то запускать? Некоторые библиотеки времени выполнения? Кстати, что делают библиотеки времени выполнения?
  • Linux: Не знаю, можете ли вы просветить меня?

Я знаю, что это зависит от компилятора и ОС, но мне нужен либо общий ответ, либо конкретные примеры. ТИА.

4b9b3361

Ответ 1

Для программ

C в Windows требуются библиотеки CRT, которые поставляются с Windows. С++ иногда требуют так называемого "С++ redistributable". Они могут быть встроены в приложение через ссылку, но это сделает EXE больше.

Ответ 2

В качестве общего ответа первым потребуются библиотеки времени выполнения С++ (материал, необходимый для поддержки стандартных вызовов библиотеки). Они образуют интерфейс между языком и библиотеками поддержки, которые, в свою очередь, знают, как добиться того, что они делают в данной среде.

Второй не использует библиотеки времени выполнения. Он будет использовать код запуска и завершения C (который инициализирует и срывает среду C), но это точка обсуждения относительно того, считаются ли они частью библиотек времени исполнения. Если вы считаете их частью, то, да, они будут использоваться. Вероятно, это будет очень небольшая часть, так как обычно существует большая разница в размере между кодом запуска и потоками.

Вы можете связать свой код статически (привязка во время соединения) с библиотеками времени выполнения или динамически (так что фактическое привязку выполняется во время загрузки). Это верно для Windows и Linux.

Ответ 3

В приложениях Windows вы можете использовать Dependency Walker для просмотра всех зависимостей.

Ответ 4

Первая программа выполняет потоковый ввод-вывод, что означает, что она должна взаимодействовать с ресурсами (console, gui), управляемыми ОС. Таким образом, в конечном счете, ОС необходимо вызывать через API, реализованный в системной DLL.

В окнах вторая программа не требует библиотек. Я уверен, что то же самое верно в Linux.

Ответ 5

Скомпилируйте их с помощью GCC и получите исполняемый файл с именем "привет", в консоли пишите:

ldd hi

предоставит вам общие объекты (динамические библиотеки), которые подключены к вашей программе.

Просто для быстрого ответа вот вывод:

ldd tifftest
  libtiff.so.3 => /usr/lib/libtiff.so.3 (0x4001d000)
  libc.so.6 => /lib/libc.so.6 (0x40060000)
  libjpeg.so.62 => /usr/lib/libjpeg.so.62 (0x40155000)
  libz.so.1 => /usr/lib/libz.so.1 (0x40174000)
  /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

Ответ 6

Хорошо, посмотрим на это с более общей точки зрения:

  • Для начала вам понадобится компьютер с совместимым процессором, который работает с целевой машиной выхода компилятора. Вы можете подумать, что это очевидно, но при условии, что код компилируется в машинный код x86, он не будет работать на процессоре Alpha, который использует разные инструкции. Кроме того, если вы компилируете машинный код x64, он не будет работать на процессоре с процессором x86. Поэтому для запуска программы на С++ необходимо использовать правильное оборудование, в отличие от языков на основе виртуальной машины, таких как Java, которые абстрагируют это.

  • Вам также понадобится правильная операционная система . Я не специалист по портированию программ, но я не думаю, что можно создать один исполняемый файл, который работает на нескольких операционных системах на С++. Например, при компиляции даже вашего второго примера в Windows будет много кода времени исполнения за кулисами до и после фактического вызова вашей функции main(). Это будет делать такие вещи, как подготовить кучу и инициализировать библиотеку CRT. CRT для Windows реализуется через Windows API. Вы можете статически связывать библиотеку так, чтобы не требовалась DLL CRT, но код в вашей программе по-прежнему вызывает вызовы в Windows API, поэтому он все еще зависит от платформы. В качестве эксперимента я скомпилировал пустую программу со статической связью в Windows с Visual Studio, и, согласно Dependency Walker, она по-прежнему ссылается на KERNEL32.DLL для таких функций, как HeapCreate и ExitProcess. Таким образом, "пустая" программа по-прежнему делает для вас целую кучу продуктов операционной системы, готовясь к чему-то полезному (независимо от того, делает ли ваша программа что-нибудь полезное).

Также обратите внимание, что может быть минимальная версия операционной системы: для Visual Studio 2010 требуется Windows XP SP2 или выше для даже пустой программы из-за вызовов, сделанных в EncodePointer и DecodePointer. См. этот вопрос.

  • Для запуска вашей программы система должна иметь память. Вы можете подумать, что он ничего не делает, но, как показано выше, до того, как main() называется целым загрузочным вызовом инициализации операционной системы, вы создаете свою библиотеку программ. Для этого, вероятно, требуется некоторая память и время обработки, необходимое для ее выполнения.

  • В зависимости от конфигурации операционной системы вам может потребоваться достаточно привилегий безопасности для запуска исполняемых программ.

Итак, короче говоря, для запуска пустой С++-программы даже со статической привязкой вам нужен правильный процессор, операционная система, разрешение на запуск исполняемого файла и время памяти/обработки для завершения программы. По сравнению с технологиями VM, такими как Java или .NET, требования сводятся к возможной правильной виртуальной машине, необходимой привилегии и требуемому времени памяти/процессора для запуска программы. Это может быть не так просто, как кажется: вам может понадобиться правильная версия виртуальной машины, например .NET framework 4.0. Это может усложнить процесс распространения, поскольку обновление всей инфраструктуры JVM или .NET для машины может быть трудоемким процессом, требующим прав администратора и, возможно, подключения к Интернету. В некоторых узких случаях это может быть прерывание сделки, поскольку в редких случаях может быть проще сказать: "он будет работать на любой x86-совместимой операционной системе Windows с XP", в отличие от "любой машины с новейшей виртуальной машина, которая была выпущена только вчера". Однако для большинства целей тот факт, что виртуальная машина позволяет вам (теоретически) забыть о процессоре и операционной системе, облегчает распределение программы; с С++ вам необходимо как минимум скомпилировать отдельные исполняемые файлы для каждой комбинации платформы и процессора, которые вы хотите поддерживать, независимо от дополнительных требований библиотек, которые вы используете.

Ответ 7

Для первой части вашего вопроса - на вас ответили несколько участников. Но то, что я говорю, является общим и обязательным для обоих случаев - (в случае, если вы не знаете)

Для любой программы, которую нужно запустить, она должна быть обеспечена необходимыми ресурсами. Отвечая на первую часть, команда уже перечисляет несколько элементов.

Но в целом, для этого требуется хорошо определенное адресное пространство (в основной памяти), его свойства и время процессора. Операционная система гарантирует, что вы получите это при выполнении своей программы. Если не будет какого-то смешного конфликта, ваша программа получит это (и именно поэтому я предполагаю, что Chubsdad прокомментировал "вам нужна удача" ).

OS scheduling, CPU, запрашивающий выбор команд/данных из памяти, а затем их выполнение... все образует "машину", которая выполняет вашу программу.

Поиск точки входа (или первой точки в вашей программе для выполнения) - это все, что решается либо во время компиляции (например, для основной функции), либо при загрузке вашей программы с использованием какого-то системного вызова, например exec() (в Unix)/CreateProcess() (в окнах).

Ответ 8

В Linux любая C-программа статически связана с некоторыми библиотеками CRT. Истинной точкой входа программы является функция _start(), определенная в /usr/lib/crt 1.o. Эта функция вызывает некоторые функции libc, такие как __libc_start_main(). Таким образом, вам все еще нужна библиотека libc...

Вы можете обойтись без libc, но это сложно. Вам нужно будет переименовать свою точку входа _start() или дать команду компоновщику начать с main(). И вам также понадобится встроенная сборка для выпуска системного вызова _exit(), когда программа будет выполнена, иначе она просто сработает. И, конечно, сделайте ссылку явно с помощью команды ld, а не через интерфейс gcc.