libstdc++-6.dll の競合

`libstdc++-6.dll`はMinGWのC++ランタイムライブラリです。
MinGWの`g++`でコンパイルされたプログラムは動作時にこのDLLを必要とします。

Windowsに移植されたLinux/Unix向けのソフトウェアにはしばしばこのDLLが含まれています。
複数の`libstdc++-6.dll`がパスにあると問題が生じることがあります。

#MSYS2

MSYS2の`mingw-w64-x86_64-gcc`で次のコードをコンパイルします。

```cpp
#include <string>
#include <iostream>

int main(){
	std::string s;
	s = "Hello World!";
	std::cout << s << '\n';
}
```

実行ファイルとして`a.exe`が吐き出されます。
これを`MinGW-w64 Win64 Shell`から実行すると、特に何の問題もなく実行されます。

しかし、それ以外の環境から実行すると問題が起きます。
`MSYS2 Shell`:出力のないまま終了
`MinGW-w64 Win32 Shell`:出力のないまま終了
コマンドプロンプト:以下のエラーで終了
![test.jpg](https://qiita-image-store.s3.amazonaws.com/0/71548/ebe1a3c5-40aa-7c66-d36c-e6ac70bfb689.jpeg)

`<string>`を使わなければ問題は起きないようなので、`<string>`を含むDLLに問題があるようです。

#原因を調べる
`objdump -p`を使うと頭の方に`The Import Tables`というのがあって、どのDLLからどの関数等を使っているかが書いてあります。

```
The Import Tables (interpreted .idata section contents)
 vma:            Hint    Time      Forward  DLL       First
                 Table   Stamp     Chain    Name      Thunk
 00008000	00008064 00000000 00000000 00008a08 0000828c

	DLL Name: libgcc_s_seh-1.dll
	vma:  Hint/Ord Member-Name Bound-To
	84b4	   14  _Unwind_Resume

 00008014	00008074 00000000 00000000 00008a48 0000829c

	DLL Name: libstdc++-6.dll
	vma:  Hint/Ord Member-Name Bound-To
	84c8	 3850  _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1Ev
	8504	 3870  _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev
	8540	 3873  _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEaSEPKc
	8580	 4421  _ZNSt8ios_base4InitC1Ev
	859c	 4423  _ZNSt8ios_base4InitD1Ev
	85b8	 4708  _ZSt4cout
	85c4	 4771  _ZSt9terminatev
	85d8	 4820  _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_c
	8610	 4828  _ZStlsIcSt11char_traitsIcESaIcEERSt13basic_ostreamIT_T0_ES7_RKNSt7__cxx1112basic_stringIS4_S5_T1_EE
	8678	 5792  __cxa_begin_catch
	868c	 5828  __gxx_personality_seh0

 00008028	000080d4 00000000 00000000 00008abc 000082fc

	DLL Name: KERNEL32.dll
	vma:  Hint/Ord Member-Name Bound-To
	86a8	  216  DeleteCriticalSection
	86c0	  249  EnterCriticalSection
	86d8	  462  GetCurrentProcess
	86ec	  463  GetCurrentProcessId
	8702	  467  GetCurrentThreadId
	8718	  529  GetLastError
	8728	  549  GetModuleHandleA
	873c	  599  GetProcAddress
	874e	  628  GetStartupInfoA
	8760	  651  GetSystemTimeAsFileTime
	877a	  678  GetTickCount
	878a	  762  InitializeCriticalSection
	87a6	  844  LeaveCriticalSection
	87be	  958  QueryPerformanceCounter
	87d8	 1029  RtlAddFunctionTable
	87ee	 1030  RtlCaptureContext
	8802	 1037  RtlLookupFunctionEntry
	881c	 1044  RtlVirtualUnwind
	8830	 1187  SetUnhandledExceptionFilter
	884e	 1200  Sleep
	8856	 1214  TerminateProcess
	886a	 1221  TlsGetValue
	8878	 1234  UnhandledExceptionFilter
	8894	 1264  VirtualProtect
	88a6	 1266  VirtualQuery

 0000803c	000081a4 00000000 00000000 00008b3c 000083cc

	DLL Name: msvcrt.dll
	vma:  Hint/Ord Member-Name Bound-To
	88b6	   55  __C_specific_handler
	88ce	   78  __dllonexit
	88dc	   81  __getmainargs
	88ec	   82  __initenv
	88f8	   83  __iob_func
	8906	   90  __lconv_init
	8916	   96  __set_app_type
	8928	   98  __setusermatherr
	893c	  115  _acmdln
	8946	  122  _amsg_exit
	8954	  140  _cexit
	895e	  251  _fmode
	8968	  330  _initterm
	8974	  439  _lock
	897c	  611  _onexit
	8986	  819  _unlock
	8990	 1030  abort
	8998	 1047  calloc
	89a2	 1060  exit
	89aa	 1079  fprintf
	89b4	 1086  free
	89bc	 1097  fwrite
	89c6	 1145  malloc
	89d0	 1153  memcpy
	89da	 1183  signal
	89e4	 1204  strlen
	89ee	 1207  strncmp
	89f8	 1239  vfprintf
```

どうやら`libstdc++-6.dll`に問題があってエラーが出たようです。

#`gnuplot`が悪い(!?)
うちの環境にはWindows用の`gnuplot`が入っていました。
このソフトのフォルダにも`libstdc++-6.dll`が入っていたのでした。

そして、`MinGW-w64 Win64 Shell`以外の環境では`gnuplot`のフォルダの方を`msys2`のフォルダより先に読みに行くので、こっちを読みに行った結果、うまく動かなかったようでした。

#結論
Windows環境ではDLLの競合に注意