【MFC】LNK2005「already defined in LIBCMTD.lib」/ nafxcw.lib:ランタイムライブラリと「MFCの使用」設定の不一致を直す

【MFC】LNK2005「already defined in LIBCMTD.lib」/ nafxcw.lib:ランタイムライブラリと「MFCの使用」設定の不一致を直す

MFCプロジェクトのリンク時に、operator newやoperator deleteなどがalready defined in LIBCMTD.lib(またはnafxcw.lib)と出るLNK2005は、まず「MFCの使用」設定とランタイム ライブラリ(/MT・/MD)の組み合わせ不一致を疑います(外部から受け取った .libが原因のこともありますが、自分のプロジェクトの設定ならすぐ確かめられるので先に見ます)。

error LNK2005: "void * __cdecl operator new(unsigned __int64)" は既に LIBCMTD.lib(new_scalar.obj) で定義されています。
fatal error LNK1169: 1 つ以上の多重定義シンボルが見つかりました。
最初に確認する症状読む記事
「MFCの使用」と/MT・/MDが合わない、または外部.libのランタイムが異なるこの記事:2つの設定と外部ライブラリを確認
スタティックMFCで、設定は合っているのにoperator newが重複するLNK2005/LNK1169とリンク順序の確認

目次

まず確認:「MFCの使用」と「ランタイム ライブラリ」を合わせる

たがいに必ずそろえる設定が2つあります。MFCのリンク方式(静的か共有DLLか)と、CRTのリンク方式(静的 /MTか 動的 /MDか)です。ここがずれると、CRTとMFCの両方がnew / deleteを定義し、重複になります。

「MFCの使用」合わせるランタイム ライブラリ
スタティック ライブラリでMFCを使用するマルチスレッド (/MT) / マルチスレッド デバッグ (/MTd)
共有DLLでMFCを使用するマルチスレッドDLL (/MD) / マルチスレッド デバッグDLL (/MDd)

エラーに出てくるライブラリ名は、どのCRT / MFCが取り込まれたかを示しています。名前から構成を逆算できます。

ライブラリ名正体
LIBCMT.lib / LIBCMTD.lib静的CRT(/MT/ /MTd)
MSVCRT.lib / MSVCRTD.lib動的CRT(/MD/ /MDd)
nafxcw.lib / nafxcwd.lib静的リンクMFC(MBCS。Release/Debug)
uafxcw.lib / uafxcwd.lib静的リンクMFC(Unicode。Release/Debug)

検証環境:Visual Studio 2026


手順1:プロジェクトの2つの設定を一致させる

自分のプロジェクトで見る設定は2つ、[MFCの使用]と[ランタイム ライブラリ]です。外部のライブラリを疑う前に、まずこちらを合わせます。

  1. プロジェクトのプロパティ → [詳細] → [MFCの使用] を確認します(静的か共有DLLか)。
  2. プロパティ → [C/C++] → [コード生成] → [ランタイム ライブラリ] を、上の早見表に合わせて設定します。
Visual Studio 2026のプロパティで 詳細 のMFCの使用設定を確認している画面
Visual Studio 2026のプロパティでC/C++ コード生成のランタイム ライブラリ設定を確認している画面

注意点は 構成ごとに設定が分かれていることです。Debug / Releaseとx86 / x64で別々に持つため、すべての構成で組み合わせが合っているか確認します。片方の構成だけ直して安心しないでください。


手順2:リンクしている外部 .libのランタイムを疑う

社内のほかのプロジェクトで作った .libや、提供元から受け取った .libが、自分のプロジェクトと違うランタイムでビルドされていることがあります。自分のプロジェクトの設定が正しいのにまだ出るなら、リンクしている外部の静的ライブラリを疑います。

たとえば、あなたのアプリが 共有DLLでMFCを使用(/MD)なのに、リンクする外部 .libが /MTでビルドされていると、その .libがLIBCMT.libを持ち込み、あなたのMSVCRT.libとnew / deleteが衝突します。

  • ソースがあるなら、その外部ライブラリをあなたのプロジェクトと同じランタイム設定で再ビルドします。これが最も安全です。
  • 提供元のバイナリしかないなら、対応するランタイムでビルドされた版を入手するか、提供元に確認します。

手順3:応急処置として /NODEFAULTLIBで競合CRTを外す

外部ライブラリを再ビルドできず、すぐ通したいときだけの応急処置です。競合している側のCRTを1つに寄せます。

  1. プロパティ → [リンカー] → [入力] → [特定の既定のライブラリの無視] を開きます。
  2. エラーで「既に定義されています」と名指しされた側のCRTを1つだけ無視に追加します(例:LIBCMTD.lib)。

この指定は、内部的にはリンカーの /NODEFAULTLIB:libcmtdオプションになります。どちらを残すかは、残したいランタイム側を生かすのが原則です(共有DLL構成ならMSVCRT(D).libを残し、静的CRT側を無視する)。

注意:CRTを混在させたまま /NODEFAULTLIBで無理にリンクを通すと、リンクは成功しても実行時にヒープやグローバル状態の不整合を起こすことがあります。恒久対策は手順1・2(設定の一致と再ビルド)です。/NODEFAULTLIBは、原因を理解したうえでの一時しのぎと考えてください。


関連記事


まとめ

  • already defined in LIBCMTD.lib系のLNK2005は、まず「MFCの使用」と「ランタイム ライブラリ」の組み合わせを合わせる。
  • 静的MFC ↔ /MT(d)、共有DLL MFC ↔ /MD(d)。全構成で確認する。
  • 設定が正しいのに出るなら、外部 .libのランタイム違いを疑い、同じ設定で再ビルドする。
  • /NODEFAULTLIBは応急処置。混在のまま通すと実行時リスクが残る。
目次