Должен ли я компилироваться с / MD или / MT?

В Visual Studio есть флаги компиляции / MD и / MT, которые позволяют вам выбрать, какую библиотеку времени выполнения вы хотите использовать.

Я понимаю разницу в реализации, но я все еще не уверен, какой из них использовать. Каковы плюсы и минусы?

Одно из преимуществ / MD, которое я слышал, заключается в том, что это позволяет кому-то обновлять среду выполнения (например, возможно, исправлять проблему безопасности), и мое приложение получит это обновление. Хотя для меня это почти похоже на не-функцию: я не хочу, чтобы люди меняли свое время выполнения, не позволяя мне протестировать новую версию!

Некоторые вещи мне интересны:

  • Как это повлияет на время сборки? (предположительно / MT немного медленнее?)
  • Каковы другие последствия?
  • Какой из них используют большинство людей?

Динамически связываясь с / MD,

  • вы подвергаетесь обновлениям системы (для хорошего или плохого),
  • ваш исполняемый файл может быть меньше (поскольку в нем нет встроенной библиотеки) и
  • Я считаю, что по крайней мере сегмент кода DLL разделяется между всеми процессами, которые активно его используют (уменьшая общий объем потребляемой RAM).

Я также обнаружил, что на практике при работе со статически связанными сторонними двоичными библиотеками, которые были созданы с разными параметрами времени исполнения, / MT в главном приложении имеет тенденцию вызывать конфликты гораздо чаще, чем / MD (потому что вы ‘столкнутся с проблемами, если время выполнения C статически связано несколько раз, особенно если это разные версии).

Если вы используете библиотеки DLL, вам следует обратиться за динамически связанным CRT (/ MD).

Если вы используете динамический CRT для вашего .exe и всех DLL-файлов, то все они будут использовать единую реализацию CRT – это означает, что все они будут иметь общую кучу CRT и память, выделенную в одном .exe / .dll, могут быть освобождены в другой.

Если вы используете статический CRT для вашего .exe и всех DLL-файлов, тогда они получат отдельную копию CRT, что означает, что все они будут использовать свою собственную кучу CRT, поэтому память должна быть освобождена в том же модуле, в котором она был выделен. Вы также будете страдать от раздувания кода (несколько копий CRT) и избыточных затрат времени выполнения (каждая куча выделяет память из ОС, чтобы отслеживать ее состояние, и накладные расходы могут быть заметными).

Я считаю, что по умолчанию для проектов, построенных через Visual Studio, есть / MD.

Если вы используете / MT, ваш исполняемый файл не будет зависеть от DLL, присутствующей в целевой системе. Если вы завершите это в установщике, это, вероятно, не будет проблемой, и вы можете пойти в любом случае.

Я сам использую / MT, чтобы я мог игнорировать весь DLL-беспорядок.

PS Как указывает г-н Фоус , важно быть последовательным. Если вы связываетесь с другими библиотеками, вам нужно использовать ту же самую опцию. Если вы используете стороннюю DLL, почти наверняка вам понадобится использовать DLL-версию библиотеки времени выполнения.

Я предпочитаю связывать статически с / MT.

Несмотря на то, что вы получаете меньший исполняемый файл с / MD, вам все равно придется отправлять кучу DLL, чтобы убедиться, что пользователь получил правильную версию для запуска вашей программы. И, в конце концов, ваш установщик будет БОЛЬШЕ, чем при соединении с / MT.

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

Проблема, с которой вы столкнетесь / MD, заключается в том, что целевая версия CRT может быть не на вашем компьютере пользователя (особенно если вы используете последнюю версию Visual Studio, а у пользователя есть более старая операционная система).

В этом случае вам нужно выяснить, как получить правильную версию на своей машине.

с http://msdn.microsoft.com/en-us/library/2kzt1wy3(VS.71).aspx :

/ MT Определяет _MT так, чтобы версии стандартных исполняемых программ из нескольких файлов были выбраны из стандартных файлов заголовка (.h). Этот параметр также заставляет компилятор помещать имя библиотеки LIBCMT.lib в файл .obj, чтобы компоновщик использовал LIBCMT.lib для разрешения внешних символов. Для создания многопоточных программ требуется либо / MT, либо / MD (или их эквиваленты отладки / MTd или / MDd).

/ MD Определяет _MT и _DLL, так что обе версии исполняемых программ с многопоточным и DLL-кодом выбираются из стандартных файлов .h. Этот параметр также заставляет компилятор помещать имя библиотеки MSVCRT.lib в файл .obj.

Приложения, скомпилированные с этой опцией, статически связаны с MSVCRT.lib. Эта библиотека предоставляет слой кода, который позволяет компоновщику разрешать внешние ссылки. Фактический рабочий код содержится в MSVCR71.DLL, который должен быть доступен во время выполнения приложениям, связанным с MSVCRT.lib.

Когда / MD используется с _STATIC_CPPLIB, определенным (/ D_STATIC_CPPLIB), это приведет к тому, что приложение будет ссылаться на статическую многопоточную стандартную библиотеку C ++ (libcpmt.lib) вместо динамической версии (msvcprt.lib), все еще динамически связывая с основным CRT через msvcrt.lib.

Поэтому, если я правильно его интерпретирую, то / MT связывает статически и / MD ссылки динамически.

Если вы создаете исполняемый файл, который использует другие dll или libs, чем опция / MD, предпочтительнее, так как все компоненты будут использовать одну и ту же библиотеку. Конечно, этот параметр должен соответствовать всем задействованным модулям, т.е. dll / lib / exe.

Если ваш исполняемый файл не использует никакие библиотеки lib или dll, как его вызов. Разница сейчас не слишком велика, поскольку аспект совместного использования не вступает в игру.

Поэтому, возможно, вы можете запустить приложение с / MT, так как нет никакой веской причины, но когда его время для добавления lib или dll, вы можете изменить его на / MD с помощью lib / dll, что легко.

  • Visual Studio (2008) «Чистое решение»
  • Замедление Microsoft Visual Studio из-за разного сканирования вирусов
  • Как вы находите все реализации интерфейса?
  • Как конкретно свойство «Специфическая версия» ссылки на сборку работает в Visual Studio?
  • Неконстантная ссылка связана с временной ошибкой Visual Studio?
  • Как объявить глобальную переменную в C ++
  • Как установить значок для моего приложения в visual studio 2008?
  • Неразрешенный внешний символ в объектных файлах
  • Каково значение тега ProjectTypeGuids в файле проекта visual studio
  • Оранжевый цвет текста в приложении консоли C #?
  • Свойство OutputPath не установлено для этого проекта
  • Давайте будем гением компьютера.