Чи слід компілювати з / MD чи / MT?


127

У Visual Studio є прапорці компіляції / MD та / MT, які дозволяють вам вибрати, який тип бібліотеки виконання C ви хочете.

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

Однією з переваг / MD, яку я чув, є те, що це дозволяє комусь оновлювати час виконання (як, можливо, виправити проблему з безпекою), і мій додаток отримає користь від цього оновлення. Хоча мені це здається нехарактерним: я не хочу, щоб люди міняли час мого виконання, не дозволяючи мені протестувати проти нової версії!

Мені цікаво щось:

  • Як це вплине на час побудови? (мабуть / MT трохи повільніше?)
  • Які інші наслідки?
  • Кого використовують більшість людей?

1
Більш детальну інформацію та пропозиції можна знайти в: stackoverflow.com/questions/787216
Weidenrinde

Відповіді:


87

Динамічно пов'язуючи з / MD,

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

Я також виявив, що на практиці при роботі зі статично пов'язаними сторонніми бінарними бібліотеками, побудованими з різними параметрами виконання, / MT в основному додатку, як правило, викликає конфлікти набагато частіше, ніж / MD (тому що ви У вас виникнуть проблеми, якщо час виконання C декілька разів статично пов'язаний, особливо якщо це різні версії).


11
Біт оновлення системи дещо скорочується за допомогою SxS. EXE отримує заявити, яку версію CRT бажає (хоче, не отримує - оновлення безпеки може перекрити це)
MSalters

1
Чи означає це, що якщо я компілюю за допомогою MD і моя програма залежить від деякого dll, програма вийде з ладу, якщо вона працює на комп'ютері, де dll залежності не існує?
gerrytan

5
@gerrytan: Так, вам потрібно буде забезпечити наявність відповідних DLL-файлів на всіх комп'ютерах, які хочуть запустити програмне забезпечення. Типовими рішеннями для цього є те, щоб користувач встановив відповідний пакет перерозподілу MSVC або застосував інсталятор, який виконує всю роботу.
Містер Фооз

@Royi Я не впевнений, але я думаю, що /MTбуде трохи швидше під час виконання, оскільки вашій програмі не потрібно шукати виконання функції виконання кожного разу, я не експерт на цьому рівні, але я майже впевнений, що більшість Операційні системи кешуватимуть виконання часу виконання, тому ваш додаток використовуватиме кешовану версію, тому різниця не буде настільки далеко, ПРИМІТКА, що я згадав, що я не впевнений, тому не сприймайте цей коментар як аргумент.
Ахмед Камаль

34

Якщо ви використовуєте DLL, то вам слід перейти до динамічно пов'язаного CRT (/ MD).

Якщо ви використовуєте динамічний CRT для свого .exe та всіх .dlls, то вони будуть спільно використовувати одну реалізацію CRT - це означає, що всі вони матимуть спільний доступ до однієї купи CRT, а пам'ять, виділена в одному .exe / .dll, може бути звільнена в інший.

Якщо ви використовуєте статичну CRT для свого .exe та всіх .dlls, то всі вони отримають окрему копію CRT - це означає, що всі вони використовуватимуть власну кучу CRT, тому пам'ять має бути звільнена в тому ж модулі, в якому вона було виділено. Ви також постраждаєте від роздуття коду (декілька копій CRT) та надмірних накладних витрат (кожна купа виділяє пам'ять з ОС для відстеження свого стану, і накладні витрати можуть бути помітні).


20

Я вважаю, що за замовчуванням для проектів, побудованих за допомогою Visual Studio, є / MD.

Якщо ви використовуєте / MT, ваш виконуваний файл не залежатиме від присутності DLL в цільовій системі. Якщо ви загортаєте це в інсталятор, це, ймовірно, не буде проблемою, і ви можете піти в будь-який бік.

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

PS Як зазначає пан Фооз , важливо бути послідовним. Якщо ви зв’язуєтесь з іншими бібліотеками, вам потрібно використовувати той самий варіант, що і вони. Якщо ви використовуєте сторонні DLL, майже впевнено, що вам потрібно буде використовувати версію DLL бібліотеки виконання.


14

Я вважаю за краще статично зв’язуватися з / MT.

Хоча ви отримуєте менший виконуваний файл з / MD, вам все одно доведеться доставити купу DLL-файлів, щоб переконатися, що користувач отримає потрібну версію для запуску вашої програми. І врешті-решт, ваш інсталятор стане ВИМОГО, ніж при зв’язуванні з / MT.

Що ще гірше, якщо ви вирішите помістити свої бібліотеки виконання у каталог Windows, рано чи пізно користувач збирається встановити нову програму з різними бібліотеками і, при будь-якій невдачі, зламати вашу програму.


5
Дуже погана ідея "помістити свої бібліотеки виконання в каталог Windows". Ви можете зламати інші німі програми, які зробили те саме, що раніше. Використовуйте SxS і дозвольте інсталятору впоратися з ним, або дотримуйтесь / MT.
MSalters

1
Я повністю згоден, що це погана ідея. Деякі люди це роблять, хоча я описував, чому це не гарна ідея.
Адріан Григоре

@AdrianGrigore Чому нова програма з різними бібліотеками спричинить зрив вашої програми? Якщо ви використовуєте / MD-зв'язок, ви просто почнете завантажувати нові версії бібліотек?
rturrado

4
@rturrado: Не зовсім. Встановлення інших додатків поверх ваших може замінити ваші DLL-версії на старіші версії. Більш нових версій не було б. Це зазвичай відомо як "dll hell", див. En.wikipedia.org/wiki/DLL_Hell
Адріан Григоре

1
Microsoft відмовилася від WinSxS у Visual Studio 2010 - бібліотеки виконання виконуються або приватно, або в system32 ( msdn.microsoft.com/en-us/library/vstudio/dd293574.aspx ).
BCran

8

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

У цьому випадку ви повинні розібратися, як отримати потрібну версію на їх машину.


7

від 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 посилання динамічно.


Питання було "яким я повинен користуватися?", Це не відповідь.
Леонард Інкрет

2

Якщо ви створюєте виконувану програму, яка використовує інші dlls або libs, ніж опція / MD, то краща опція / MD, оскільки таким чином всі компоненти будуть спільно використовуватися в одній бібліотеці. Звичайно, ця опція повинна відповідати всім модулям, що стосуються, тобто dll / lib / exe.

Якщо ваш виконуваний файл не використовує жодної lib або dll, ніж його дзвінок. Зараз різниця не надто велика, оскільки аспект спільного використання не грає.

Тож, можливо, ви можете запустити програму з / MT, оскільки немає переконливої ​​причини інакше, але коли прийде час додати lib або dll, ви можете змінити його на / MD з lib / dll, що легко.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.