Haruskah saya kompilasi dengan / MD atau / MT?

126

Di Visual Studio, ada flag kompilasi / MD dan / MT yang memungkinkan Anda memilih jenis perpustakaan runtime C yang Anda inginkan.

Saya mengerti perbedaan dalam implementasi, tetapi saya masih tidak yakin yang mana yang akan digunakan. Apa pro / kontra?

Salah satu keuntungan / MD yang saya dengar, adalah ini memungkinkan seseorang untuk memperbarui runtime, (seperti mungkin memperbaiki masalah keamanan) dan aplikasi saya akan mendapat manfaat dari pembaruan ini. Meskipun bagi saya, ini hampir tampak seperti fitur non-: Saya tidak ingin orang mengubah runtime saya tanpa mengizinkan saya untuk menguji terhadap versi baru!

Beberapa hal yang membuat saya penasaran:

  • Bagaimana ini akan memengaruhi waktu membangun? (agaknya / MT sedikit lebih lambat?)
  • Apa implikasi lainnya?
  • Mana yang paling banyak digunakan orang?
andy
sumber
1
Informasi dan saran lebih lanjut dapat ditemukan di: stackoverflow.com/questions/787216
Weidenrinde

Jawaban:

85

Dengan menghubungkan secara dinamis dengan / MD,

  • Anda terpapar pembaruan sistem (baik atau buruk),
  • executable Anda bisa lebih kecil (karena tidak memiliki pustaka yang tertanam di dalamnya), dan
  • Saya percaya bahwa setidaknya segmen kode DLL dibagi di antara semua proses yang secara aktif menggunakannya (mengurangi jumlah total RAM yang dikonsumsi).

Saya juga menemukan bahwa dalam praktiknya, ketika bekerja dengan perpustakaan biner pihak ke-3 yang terhubung secara statis yang telah dibangun dengan opsi runtime yang berbeda, / MT dalam aplikasi utama cenderung menyebabkan konflik lebih sering daripada / MD (karena Anda akan mengalami masalah jika runtime C dihubungkan secara statis beberapa kali, terutama jika mereka versi yang berbeda).

Tuan Fooz
sumber
10
Bit pembaruan sistem agak berkurang oleh SxS. EXE dapat mendeklarasikan versi CRT yang diinginkannya (ingin, tidak mendapat - pembaruan keamanan mungkin mengesampingkan ini)
MSalters
1
Apakah ini berarti jika saya mengkompilasi menggunakan MD dan program saya tergantung pada beberapa dll, program akan gagal jika berjalan di komputer di mana dependensi dll tidak ada?
gerrytan
5
@gerrytan: Ya, Anda harus memastikan bahwa DLL yang sesuai digunakan di semua komputer yang ingin menjalankan perangkat lunak. Solusi khas untuk ini adalah membuat pengguna menginstal paket redistributable MSVC yang sesuai, atau menggunakan installer yang melakukan semua pekerjaan.
Tn. Fooz
@Royi Saya tidak yakin tapi saya pikir /MTakan sedikit lebih cepat saat runtime karena aplikasi Anda tidak perlu mencari implementasi fungsi runtime setiap kali, saya bukan ahli di level ini tapi saya cukup yakin sebagian besar OS akan men-cache implementasi runtime sehingga aplikasi Anda akan menggunakan versi yang di-cache, jadi perbedaannya tidak akan terlalu jauh, CATATAN yang saya sebutkan bahwa saya tidak yakin jadi jangan menganggap komentar ini sebagai argumen.
Ahmed Kamal
34

Jika Anda menggunakan DLL maka Anda harus menggunakan CRT (/ MD) yang terhubung secara dinamis.

Jika Anda menggunakan CRT dinamis untuk .exe dan semua. lain.

Jika Anda menggunakan CRT statis untuk .exe dan semua .dlls maka mereka semua akan mendapatkan salinan CRT yang terpisah - yang berarti mereka semua akan menggunakan tumpukan CRT mereka sendiri sehingga memori harus dibebaskan dalam modul yang sama di mana ia dialokasikan. Anda juga akan menderita kode mengasapi (beberapa salinan CRT) dan kelebihan overhead runtime (setiap heap mengalokasikan memori dari OS untuk melacak keadaannya, dan overhead dapat terlihat).

JoeG
sumber
20

Saya percaya standar untuk proyek yang dibangun melalui Visual Studio adalah / MD.

Jika Anda menggunakan / MT, executable Anda tidak akan bergantung pada DLL yang ada pada sistem target. Jika Anda membungkus ini dengan installer, itu mungkin tidak akan menjadi masalah dan Anda bisa memilih yang mana saja.

Saya menggunakan / MT sendiri, sehingga saya bisa mengabaikan seluruh kekacauan DLL.

PS Seperti yang ditunjukkan oleh Pak Fooz , penting untuk konsisten. Jika Anda terhubung dengan perpustakaan lain, Anda perlu menggunakan opsi yang sama seperti yang mereka lakukan. Jika Anda menggunakan DLL pihak ketiga, hampir pasti Anda harus menggunakan versi DLL dari perpustakaan runtime.

Mark tebusan
sumber
14

Saya lebih suka menghubungkan secara statis dengan / MT.

Meskipun Anda mendapatkan executable yang lebih kecil dengan / MD, Anda masih harus mengirimkan banyak DLL untuk memastikan pengguna mendapatkan versi yang tepat untuk menjalankan program Anda. Dan pada akhirnya installer Anda akan menjadi LEBIH BESAR daripada saat menghubungkan dengan / MT.

Yang lebih parah lagi, jika Anda memilih untuk meletakkan pustaka runtime di direktori windows, cepat atau lambat pengguna akan menginstal aplikasi baru dengan pustaka yang berbeda dan, dengan sedikit sial, hancurkan aplikasi Anda.

Adrian Grigore
sumber
5
Ide yang sangat buruk untuk "menempatkan perpustakaan runtime Anda di direktori windows". Anda dapat merusak aplikasi bodoh lainnya yang melakukan hal yang sama sebelum melakukannya. Gunakan SxS dan biarkan pemasang menanganinya, atau tetap dengan / MT.
MSalters
1
Saya sepenuhnya setuju bahwa itu adalah Ide yang buruk. Beberapa orang melakukannya, jadi saya menjelaskan mengapa ini bukan ide yang baik.
Adrian Grigore
@AdrianGrigore mengapa aplikasi baru dengan pustaka yang berbeda menyebabkan putusnya aplikasi Anda? Jika Anda menggunakan / tautan MD, Anda hanya akan mulai memuat versi baru perpustakaan, bukan?
rturrado
4
@ Artrado: tidak cukup. Menginstal aplikasi lain di atas Anda mungkin menimpa dll Anda dengan versi yang lebih lama. Versi yang lebih baru akan hilang. Ini umumnya dikenal sebagai "dll neraka", lihat en.wikipedia.org/wiki/DLL_Hell
Adrian Grigore
1
Microsoft menyerah pada WinSxS di Visual Studio 2010 - pustaka runtime sekarang dikerahkan secara pribadi atau di system32 ( msdn.microsoft.com/en-us/library/vstudio/dd293574.aspx ).
BCran
8

Masalah yang akan Anda hadapi / MD adalah bahwa versi target CRT mungkin tidak ada di mesin pengguna Anda (terutama jika Anda menggunakan Visual Studio versi terbaru dan pengguna memiliki sistem operasi yang lebih lama).

Dalam hal ini Anda harus mencari cara untuk mendapatkan versi yang tepat di mesin mereka.

i_am_jorf
sumber
7

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

/ MT Menentukan _MT sehingga versi multithread khusus dari rutinitas run-time dipilih dari file header standar (.h). Opsi ini juga menyebabkan kompiler untuk menempatkan nama perpustakaan LIBCMT.lib ke file .obj sehingga linker akan menggunakan LIBCMT.lib untuk menyelesaikan simbol eksternal. Baik / MT atau / MD (atau yang setara dengan debug / MTd atau / MDd) diperlukan untuk membuat program multithreaded.

/ MD Menentukan _MT dan _DLL sehingga versi multithread dan DLL khusus dari rutinitas run-time dipilih dari file .h standar. Opsi ini juga menyebabkan kompiler untuk menempatkan nama perpustakaan MSVCRT.lib ke file .obj.

Aplikasi yang dikompilasi dengan opsi ini secara statis terhubung ke MSVCRT.lib. Pustaka ini menyediakan lapisan kode yang memungkinkan tautan untuk menyelesaikan referensi eksternal. Kode kerja aktual terkandung dalam MSVCR71.DLL, yang harus tersedia pada saat dijalankan untuk aplikasi yang terhubung dengan MSVCRT.lib.

Ketika / MD digunakan dengan _STATIC_CPPLIB didefinisikan (/ D_STATIC_CPPLIB) itu akan menyebabkan aplikasi untuk menautkan dengan Perpustakaan C ++ standar multithread statis (libcpmt.lib) alih-alih versi dinamis (msvcprt.lib) sementara masih secara dinamis menghubungkan ke CRT utama melalui msvcrt.lib.

Jadi jika saya mengartikannya dengan benar maka / tautan MT statis dan / tautan MD secara dinamis.

lothar
sumber
Pertanyaannya adalah "yang mana yang harus saya gunakan?", Ini bukan jawaban.
Leonard Inkret
1

Jika Anda membangun executable yang menggunakan dll atau lib lain daripada / MD opsi lebih disukai karena dengan cara itu semua komponen akan berbagi perpustakaan yang sama. Tentu saja opsi ini harus cocok untuk semua modul yang terlibat yaitu dll / lib / exe.

Jika executable Anda tidak menggunakan lib atau dll daripada panggilan siapa pun. Perbedaannya tidak terlalu banyak sekarang karena aspek berbagi tidak berlaku.

Jadi mungkin Anda dapat memulai aplikasi dengan / MT karena tidak ada alasan kuat sebaliknya, tetapi ketika saatnya untuk menambahkan lib atau dll, Anda dapat mengubahnya ke / MD dengan lib / dll yang mudah.

zar
sumber