web-dev-qa-db-fra.com

Dois-je compiler avec / MD ou / MT?

Dans Visual Studio, les indicateurs de compilation/MD et/MT vous permettent de choisir le type de bibliothèque d'exécution C que vous souhaitez.

Je comprends la différence de mise en œuvre, mais je ne sais toujours pas lequel utiliser. Quels sont les avantages/inconvénients?

Un des avantages de/MD que j'ai entendu, c'est que cela permet à quelqu'un de mettre à jour le moteur d'exécution (comme par exemple, corriger un problème de sécurité) et mon application bénéficiera de cette mise à jour. Bien que cela m’apparaisse presque comme une non-fonctionnalité: je ne veux pas que les gens changent d’exécution sans me permettre de tester la nouvelle version!

Quelques choses qui m'intriguent:

  • Comment cela affecterait-il les temps de construction? (vraisemblablement/MT est un peu plus lent?)
  • Quelles sont les autres implications?
  • Lequel la plupart des gens utilisent?
114
andy

En reliant dynamiquement avec/MD,

  • vous êtes exposé aux mises à jour du système (pour le meilleur ou pour le pire),
  • votre exécutable peut être plus petit (puisqu'il ne contient pas de bibliothèque), et
  • Je crois qu'au moins le segment de code d'un DLL est partagé entre tous les processus qui l'utilisent activement (ce qui réduit le montant total de RAM consommé).

J'ai également constaté qu'en pratique, lorsque vous travaillez avec des bibliothèques binaires tierces liées statiquement et construites avec différentes options d'exécution,/MT dans l'application principale a tendance à causer des conflits beaucoup plus souvent que/MD (parce que Vous rencontrerez des problèmes si le moteur d’exécution C est lié plusieurs fois de manière statique, en particulier s’il s’agit de versions différentes.

77
Mr Fooz

Si vous utilisez des DLL, optez pour le CRT lié dynamiquement (/ MD).

Si vous utilisez le tube cathodique dynamique pour votre fichier .exe et tous les fichiers .dll, ils partageront tous une seule implémentation du tube cathodique - ce qui signifie qu'ils partageront tous un seul segment CRT et que la mémoire allouée dans un fichier .exe/.dll pourra être libérée. un autre.

Si vous utilisez le tube cathodique statique pour votre fichier .exe et tous les fichiers .dll, ils recevront tous une copie distincte du tube cathodique - ce qui signifie qu'ils utiliseront tous leur propre tas de tube cathodique; la mémoire doit donc être libérée dans le même module que celui-ci. a été alloué. Vous allez également souffrir de gonflement du code (plusieurs copies du CRT) et de temps système excessif (chaque segment alloue de la mémoire à partir du système d’exploitation pour garder une trace de son état, ce qui peut être perceptible).

30
JoeG

Je crois que la valeur par défaut pour les projets créés avec Visual Studio est/MD.

Si vous utilisez/MT, votre exécutable ne dépendra pas de la présence de DLL sur le système cible. Si vous intégrez ceci dans un programme d'installation, ce ne sera probablement pas un problème et vous pouvez aller dans les deux sens.

J'utilise moi-même/MT pour pouvoir ignorer tout le désordre DLL.

P.S. Comme M. Fooz le souligne, il est essentiel d’être cohérent. Si vous établissez des liens avec d'autres bibliothèques, vous devez utiliser la même option. Si vous utilisez une DLL tierce, il est presque certain que vous aurez besoin d'utiliser la version DLL de la bibliothèque d'exécution.

18
Mark Ransom

Je préfère établir un lien statique avec/MT.

Même si vous obtenez un fichier exécutable plus petit avec/MD, vous devez quand même envoyer un ensemble de DLL pour vous assurer que l'utilisateur obtient la bonne version pour exécuter votre programme. Et à la fin, votre installateur sera plus gros que lors de la liaison avec/MT.

Pire encore, si vous choisissez de placer vos bibliothèques d'exécution dans le répertoire Windows, l'utilisateur installera tôt ou tard une nouvelle application avec différentes bibliothèques et, avec un malheur quelconque, casse votre application.

14
Adrian Grigore

Le problème que vous rencontrerez avec/MD est que la version cible du tube cathodique ne se trouve peut-être pas sur la machine de vos utilisateurs (surtout si vous utilisez la dernière version de Visual Studio et que l'utilisateur dispose d'un système d'exploitation plus ancien).

Dans ce cas, vous devez trouver comment obtenir la bonne version sur leur ordinateur.

8
i_am_jorf

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

/ MT Définit _MT pour que les versions des routines d'exécution spécifiques à plusieurs couches soient sélectionnées dans les fichiers d'en-tête standard (.h). Cette option force également le compilateur à placer le nom de bibliothèque LIBCMT.lib dans le fichier .obj afin que l'éditeur de liens utilise LIBCMT.lib pour résoudre les symboles externes./MT ou/MD (ou leurs équivalents de débogage/MTd ou/MDd) sont requis pour créer des programmes multithreads.

/ MD Définit _MT et _DLL de manière à ce que les versions des routines d'exécution spécifiques à la fonction multithread et à la DLL soient sélectionnées à partir des fichiers .h standard. Cette option amène également le compilateur à placer le nom de bibliothèque MSVCRT.lib dans le fichier .obj.

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

Lorsque/MD est utilisé avec _STATIC_CPPLIB défini (/ D_STATIC_CPPLIB), l'application est liée à la bibliothèque standard multithread statique C++ Library (libcpmt.lib) au lieu de la version dynamique (msvcprt.lib) tout en restant en liaison dynamique avec le CRT principal via msvcrt.lib.

Donc, si je l’interprète correctement, alors /MT établit un lien statique et /MD liens dynamiquement.

7
lothar

Si vous construisez un exécutable qui utilise d'autres dll ou bibliothèques que l'option/MD est préférable, car ainsi tous les composants partageront la même bibliothèque. Bien entendu, cette option devrait correspondre pour tous les modules impliqués, à savoir dll/lib/exe.

Si votre exécutable n'utilise aucune lib ou dll que l'appel de n'importe qui. La différence n’est pas trop grande maintenant car l’aspect partage n’est pas en jeu.

Alors peut-être que vous pouvez démarrer l’application avec/MT car il n’ya pas de raison convaincante, mais quand il est temps d’ajouter une lib ou une dll, vous pouvez le changer en/MD avec celui de la lib/dll, ce qui est facile.

1
zar