Dois-je compiler avec /MD ou /MT?

dans Visual Studio, il y a les options de compilation /MD et /MT qui vous permettent de choisir le type de bibliothèque d'exécution C que vous voulez.

je comprends la différence dans la mise en œuvre, mais je ne suis pas encore sûr de celui à utiliser. Quels sont les avantages/inconvénients?

un avantage pour /MD que j'ai entendu, est que cela permet à quelqu'un de mettre à jour l'exécution, (comme peut-être corriger un problème de sécurité) et mon application bénéficiera de cette mise à jour. Bien que pour moi, c'est presque semble comme une non-fonctionnalité: Je ne veux pas que les gens changent mon runtime sans me permettre de tester contre la nouvelle version!

certaines choses qui m'intéressent:

  • quelle incidence cela aurait-il sur les délais de construction? (probablement /MT est un peu plus lent?)
  • quelles sont les autres implications?
  • lequel est le plus utilisé?
103
demandé sur andy 2009-04-16 22:22:54

7 réponses

En reliant dynamiquement avec /MD,

  • vous êtes exposé à des mises à jour du système (en bien ou en mal),
  • votre exécutable peut être plus petit (puisqu'il ne contient pas la bibliothèque), et
  • je crois qu'au moins le segment de code D'une DLL est partagé entre tous les processus qui l'utilisent activement (réduisant la quantité totale de mémoire vive consommée).

j'ai aussi trouvé en pratique, lorsque vous travaillez avec des bibliothèques binaires de tiers liées statiquement qui ont été construites avec différentes options d'exécution, /MT dans l'application principale a tendance à provoquer des conflits beaucoup plus souvent que /MD (parce que vous allez avoir des problèmes si L'exécution C est liée statiquement plusieurs fois, surtout s'il s'agit de versions différentes).

69
répondu Mr Fooz 2009-04-16 18:49:54

si vous utilisez DLLs, vous devez choisir le CRT (/MD) dynamiquement lié.

si vous utilisez le CRT dynamique pour votre .exe et tout .les dlls partageront alors tous une seule implémentation du TRC - ce qui signifie qu'ils partageront tous un même tas de TRC et une seule mémoire allouée en un seul .EXE./dll peut être libéré dans l'autre.

si vous utilisez le CRT statique pour votre .exe et tout .les dlls auront une copie séparée de la CRT. ils vont tous utiliser leur propre tas CRT donc la mémoire doit être libérée dans le même module dans lequel il a été alloué. Vous souffrirez aussi de code bloat (copies multiples du CRT) et de dépassement de temps d'exécution (chaque tas alloue de la mémoire à partir de L'OS pour garder une trace de son état, et le dépassement peut être perceptible).

29
répondu Joe Gauterin 2013-02-03 21:32:43

je crois que la valeur par défaut pour les projets construits par Visual Studio est /MD.

si vous utilisez /MT, votre exécutable ne dépendra pas de la présence d'une DLL sur le système cible. Si vous l'emballez dans un installateur, il ne sera probablement pas un problème et vous pouvez aller dans les deux sens.

j'utilise /MT moi-même, de sorte que je peux ignorer l'ensemble du gâchis DLL.

P. S. As Mr.Fooz souligne, il est essentiel d'être cohérent. Si vous êtes le lien avec d'autres bibliothèques, vous devez utiliser la même option qu'ils font. Si vous utilisez une DLL tierce partie, il est presque certain que vous aurez besoin d'utiliser la version DLL de la bibliothèque runtime.

16
répondu Mark Ransom 2017-05-23 10:30:59

je préfère lier statiquement avec /MT.

même si vous avez un plus petit exécutable avec /MD, vous devez quand même envoyer un tas de DLLs pour vous assurer que l'utilisateur obtienne la bonne version pour exécuter votre programme. Et en fin de compte, votre installateur sera plus grand que lorsque vous liez avec /MT.

qu'est-ce qui est encore pire, si vous choisissez de mettre vos bibliothèques runtime dans le répertoire windows, tôt ou tard l'utilisateur va installer un nouveau application avec différentes bibliothèques et, avec un peu de malchance, casser votre application.

13
répondu Adrian Grigore 2009-04-16 18:59:20

le problème que vous allez rencontrer avec /MD est que la version cible du CRT peut ne pas être sur votre machine utilisateur (surtout si vous utilisez la dernière version de Visual Studio et que l'Utilisateur a un système d'exploitation plus ancien).

Dans ce cas, vous devez comprendre comment obtenir la bonne version sur leur machine.

8
répondu i_am_jorf 2009-04-16 19:00:54

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

/MT Définit _MT afin que multithread avec des versions spécifiques de l'exécution des routines sont sélectionnés à partir de la norme en-tête (.h) des fichiers. Cette option permet également au compilateur de placer le nom de la bibliothèque LIBCMT.lib dans le .obj file pour que le linker utilise LIBCMT.lib pour résoudre les symboles externes. / MT ou / MD (ou leurs équivalents debug / MTd ou /MDd) est nécessaire pour créer des programmes multithread.

/ MD définit _MT et _DLL de sorte que les versions multithread et DLL - spécifiques des routines d'exécution sont sélectionnées à partir de la norme .h fichiers. Cette option permet également au compilateur de placer le nom de la bibliothèque MSVCRT.lib dans le .fichier obj.

les Applications compilées avec cette option sont statiquement liées à MSVCRT.lib. Cette bibliothèque fournit une couche de code qui permet au linker de résoudre les références externes. Le code de travail réel est contenu dans MSVCR71.DLL, qui doit être disponible à l'exécution des applications liées à MSVCRT.lib.

Lorsque /MD est utilisé avec _STATIC_CPPLIB défini (/D_STATIC_CPPLIB) il sera la cause de la demande de lien avec la statique multithread la Bibliothèque C++ Standard (libcpmt.lib) au lieu de la version dynamique (msvcprt.lib) tout en maintenant une liaison dynamique avec le TRC principal via msvcrt.lib.

donc si je l'interprète correctement alors /MT se lie statiquement et /MD se lie dynamiquement.

5
répondu lothar 2009-04-16 18:33:38

si vous construisez un exécutable qui utilise d'autres options dlls ou libs than /MD est préféré parce que de cette façon tous les composants partageront la même bibliothèque. Bien sûr, cette option devrait correspondre à tous les modules impliqués I. e dll / lib / exe.

si votre exécutable n'utilise pas de lib ou de dll plus que son appel. La différence n'est pas trop grande maintenant parce que l'aspect du partage n'est pas en jeu.

alors peut-être que vous pouvez commencer l'application avec / MT puisqu'il n'y a pas de raison impérieuse autrement, mais quand son temps pour ajouter une lib ou dll, vous pouvez le changer en /MD avec celui de la lib/dll qui est facile.

1
répondu zar 2015-06-02 13:56:08