Должен ли я компилировать с /MD или /MT?
в Visual Studio есть флаги компиляции / MD и / MT, которые позволяют выбрать, какую библиотеку времени выполнения C вы хотите.
Я понимаю разницу в реализации, но я все еще не уверен, какой из них использовать. Какие плюсы/минусы?
одно преимущество для /MD, которое я слышал, заключается в том, что это позволяет кому-то обновлять среду выполнения (например, исправлять проблему безопасности), и мое приложение выиграет от этого обновления. Хотя для меня это почти похоже не-особенность: я не хочу, чтобы люди меняли мою среду выполнения, не позволяя мне протестировать новую версию!
некоторые вещи мне любопытно:
- как это повлияет на время? (предположительно /MT немного медленнее?)
- каковы другие последствия?
- какой из них используют большинство людей?
7 ответов:
путем динамического связывания с /MD,
- вы подвержены системным обновлениям (хорошо или плохо),
- ваш исполняемый файл может быть меньше (так как в нем нет встроенной библиотеки), и
- Я считаю, что по крайней мере сегмент кода DLL является общим для всех процессов, которые активно его используют (уменьшая общий объем потребляемой оперативной памяти).
Я также обнаружил, что на практике, при работе со статически связанными Сторонние двоичные библиотеки, которые были построены с различными параметрами выполнения, /MT в главном приложении, как правило, вызывают конфликты гораздо чаще, чем /MD (потому что вы столкнетесь с проблемами, если среда выполнения C статически связана несколько раз, особенно если они разные версии).
Если вы используете DLL, то вы должны пойти на динамически связанный CRT (/MD).
Если вы используете динамический ЭЛТ для вашего .exe и все .затем все они будут совместно использовать одну реализацию CRT - что означает, что все они будут совместно использовать одну кучу CRT и память, выделенную в одном .исполняемый./dll можно освободить в другой.
Если вы используете статический ЭЛТ для вашего .exe и все .DLL тогда они все получат отдельную копию CRT - что означает, что они все будут использовать свои собственные CRT heap поэтому память должна быть освобождена в том же модуле, в котором она была выделена. Вы также будете страдать от раздувания кода (несколько копий CRT) и избыточных накладных расходов во время выполнения (каждая куча выделяет память из ОС, чтобы отслеживать ее состояние, и накладные расходы могут быть заметны).
Я считаю, что по умолчанию для проектов, построенных с помощью Visual Studio, используется /MD.
Если вы используете /MT, ваш исполняемый файл не будет зависеть от наличия DLL в целевой системе. Если вы обертываете это в установщике, это, вероятно, не будет проблемой, и вы можете пойти в любом случае.
Я сам использую /MT, так что я могу игнорировать весь беспорядок DLL.
P. S. Как Г-Н Fooz указывает, что очень важно быть последовательным. Если вы связываетесь с другими библиотеками, вы нужно использовать тот же вариант, что и они. Если вы используете стороннюю библиотеку DLL, почти наверняка вам потребуется использовать версию DLL библиотеки времени выполнения.
Я предпочитаю связываться статически с /MT.
даже если вы получаете меньший исполняемый файл с /MD, вам все равно нужно отправить кучу DLL, чтобы убедиться, что пользователь получает правильную версию для запуска вашей программы. И в конце концов ваш установщик будет больше, чем при связывании с /MT.
Что еще хуже, если вы решите поместить свои библиотеки времени выполнения в каталог windows, рано или поздно пользователь установит новое приложение с другим библиотеки и, при любой неудаче, сломать ваше приложение.
проблема, с которой вы столкнетесь с /MD, заключается в том, что целевая версия CRT может не находиться на вашем компьютере пользователей (особенно если вы используете последнюю версию Visual Studio, а пользователь имеет более старую операционную систему).
в таком случае вы должны выяснить, как получить правильную версию на свой компьютер.
с http://msdn.microsoft.com/en-us/library/2kzt1wy3(против.71).аспн:
/MT определяет _MT таким образом, что многопоточные версии подпрограмм времени выполнения выбираются из стандартного заголовка (.ч) файлы. Этот параметр также заставляет компилятор размещать имя библиотеки LIBCMT.lib в .obj-файл, чтобы компоновщик использовал LIBCMT.lib для разрешения внешних символов. Либо /MT или /MD (или их отладочные эквиваленты /MTd или / MDd) требуется создать многопоточные программы.
/MD определяет _MT и _DLL так, чтобы и многопоточные и DLL - специфические версии подпрограмм времени выполнения были выбраны из стандарта .H-файлы. Этот параметр также заставляет компилятор размещать имя библиотеки MSVCRT.lib в .файл obj.
приложения, скомпилированные с этой опцией, статически связаны с MSVCRT.движение за освобождение. Эта библиотека предоставляет слой кода, который позволяет компоновщику разрешать внешние ссылки. Фактическая работа код содержится в MSVCR71.DLL, которая должна быть доступна во время выполнения для приложений, связанных с MSVCRT.движение за освобождение.
когда /MD используется с _static_cpplib defined (/D_STATIC_CPPLIB), это приведет к тому, что приложение будет связано со статической многопоточной стандартной библиотекой C++ (libcpmt.lib) вместо динамической версии (msvcprt.lib) при одновременном динамическом подключении к основной ЭЛТ через msvcrt.движение за освобождение.
Так что если я правильно его интерпретирую, то / MT ссылки статически и / MD динамически ссылки.
Если вы создаете исполняемый файл, который использует другие библиотеки DLL или библиотеки, чем параметр /MD, предпочтительнее, потому что таким образом все компоненты будут совместно использовать одну и ту же библиотеку. Конечно, этот параметр должен соответствовать для всех модулей, участвующих т. е. dll / lib / exe.
Если ваш исполняемый файл не использует lib или dll, чем его чей-либо вызов. Теперь разница не слишком велика, потому что аспект совместного использования не в игре.
Так что, возможно, вы можете запустить приложение с /MT, так как нет убедительная причина в противном случае, но когда пришло время добавить lib или dll, вы можете изменить его на /MD с помощью lib/dll, что легко.
Comments