web-dev-qa-db-ja.com

/ MDまたは/ MTでコンパイルする必要がありますか?

Visual Studioには、必要なCランタイムライブラリの種類を選択できるコンパイルフラグ/ MDおよび/ MTがあります。

実装の違いは理解していますが、どちらを使用するかはまだわかりません。長所と短所は何ですか?

私が聞いた/ MDの利点の1つは、これにより誰かがランタイムを更新できることであり(セキュリティ問題にパッチを当てるなど)、私のアプリはこの更新の恩恵を受けます。私にとっては、これはほとんど機能ではないように見えます。新しいバージョンに対してテストすることを許可せずに、ユーザーがランタイムを変更するのは望ましくありません。

私が興味があること:

  • これはビルド時間にどのように影響しますか? (おそらく/ MTは少し遅いですか?)
  • その他の影響は何ですか?
  • ほとんどの人はどちらを使用しますか?
114
andy

/ MDと動的にリンクすることにより、

  • システムの更新(善悪を問わず)にさらされている場合、
  • 実行可能ファイルは小さくすることができます(ライブラリが埋め込まれていないため)
  • 少なくともDLLのコードセグメントは、それをアクティブに使用しているすべてのプロセス間で共有されている(RAM消費量の合計)を減らしていると思います。

また、実際には、異なるランタイムオプションでビルドされた静的にリンクされたサードパーティのバイナリのみのライブラリを操作する場合、メインアプリケーションの/ MTは/ MDよりもはるかに頻繁に競合を引き起こす傾向があることを発見しました( Cランタイムが複数回静的にリンクされている場合、特にバージョンが異なる場合は、問題が発生します)。

77
Mr Fooz

DLLを使用している場合は、動的にリンクされたCRT(/ MD)を使用する必要があります。

.exeおよびすべての.dllに動的CRTを使用する場合、それらはすべてCRTの単一の実装を共有します。つまり、すべてが単一のCRTヒープを共有し、1つの.exe/.dllに割り当てられたメモリは別の。

.exeとすべての.dllに静的CRTを使用すると、それらはすべてCRTの個別のコピーを取得します。つまり、すべてが独自のCRTヒープを使用するため、同じモジュールでメモリを解放する必要があります。割り当てられました。また、コードの膨張(CRTの複数のコピー)と過剰なランタイムオーバーヘッド(各ヒープはOSからメモリを割り当ててその状態を追跡するため、オーバーヘッドが顕著になる可能性があります)に悩まされます。

30
JoeG

Visual Studioでビルドされたプロジェクトのデフォルトは/ MDであると思います。

/ MTを使用する場合、実行可能ファイルは、ターゲットシステムに存在するDLLに依存しません。インストーラーでこれをラップしている場合は、おそらく問題になりません。どちらの方法でも行くことができます。

自分で/ MTを使用しているので、DLL mess。

追伸 Mr。Fooz が指摘するように、一貫性を保つことが重要です。他のライブラリとリンクしている場合、それらと同じオプションを使用する必要があります。サードパーティのDLLを使用している場合は、ランタイムライブラリのDLLバージョンを使用する必要があることはほぼ確実です。

18
Mark Ransom

/ MTと静的にリンクすることを好みます。

/ MDを使用して小さな実行可能ファイルを取得しても、ユーザーがプログラムを実行するための適切なバージョンを取得できるように、多数のDLLを出荷する必要があります。そして、最終的には、インストーラーは/ MTでリンクする場合よりも大きくなります。

さらに悪いことに、ランタイムライブラリをwindowsディレクトリに配置することを選択した場合、遅かれ早かれ、ユーザーは異なるライブラリを使用して新しいアプリケーションをインストールし、運が悪ければアプリケーションを中断します。

14
Adrian Grigore

/ MDで発生する問題は、CRTのターゲットバージョンがユーザーのマシン上にない可能性があることです(特に、最新バージョンのVisual Studioを使用しており、ユーザーが古いオペレーティングシステムを使用している場合)。

その場合、適切なバージョンをマシンにインストールする方法を理解する必要があります。

8
i_am_jorf

from 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に含まれています。MSVCR71.DLLは、実行時にMSVCRT.libにリンクされたアプリケーションで使用可能でなければなりません。

定義された_STATIC_CPPLIB(/ D_STATIC_CPPLIB)で/ MDが使用されると、アプリケーションは、動的バージョン(msvcprt.lib)ではなく静的マルチスレッド標準C++ライブラリ(libcpmt.lib)とリンクしますが、メインCRT msvcrt.lib。

したがって、正しく解釈している場合、/ MTは静的にリンクし、/ MD動的にリンクします。

7
lothar

/ MDオプション以外のdllまたはlibを使用する実行可能ファイルを構築する場合は、すべてのコンポーネントが同じライブラリを共有するため、/ MDオプションが推奨されます。もちろん、このオプションは関連するすべてのモジュール、つまりdll/lib/exeに一致する必要があります。

実行可能ファイルが、誰の呼び出しよりもlibまたはdllを使用しない場合。共有の側面が役に立たないため、違いは今ではあまりありません。

そうでない場合は、/ MTを使用してアプリケーションを起動できますが、それ以外の理由はありませんが、libまたはdllを追加するときは、lib/dllの/ MDに簡単に変更できます。

1
zar