Должен ли я скомпилировать с / MD или / MT? - PullRequest
113 голосов
/ 16 апреля 2009

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

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

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

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

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

Ответы [ 7 ]

75 голосов
/ 16 апреля 2009

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

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

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

29 голосов
/ 04 сентября 2009

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

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

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

18 голосов
/ 16 апреля 2009

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

.

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

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

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

14 голосов
/ 16 апреля 2009

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

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

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

8 голосов
/ 16 апреля 2009

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

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

7 голосов
/ 16 апреля 2009

от 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), в то же время динамически связывая основной ЭЛТ через msvcrt.lib.

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

1 голос
/ 11 марта 2014

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

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

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

...