numeric_limits on Borland 5.82

昨日Borland 5.82でnumeric_limitsがおかしい問題を調査しました。
まず、Dinkumwareのコードが合っているか検証します。
std::numeric_limits<long double>::quiet_NaN()の実体はxlvalues.cの_LNanです。
このファイルを単体でコンパイルすると、_LNanの値は、

7FFFC000000000000000

になりました。これは正しい値です。
次に、CRTライブラリcw32.libからxlvalues.objを取り出し(tdump cw32.lib *xlvalues.obj)て、ダンプしてみます。

7FFFC000000000000000

これまた正しい値です。
今度はC++プログラムからダンプしてみます。

FFF8000000000000

ここでおかしくなりました。xlvalues.objは正しいのにリンクした結果がおかしいということは、別のシンボルがリンクされている可能性が高いです。
念のため、

bcc32 test.cpp xlvalues.obj

として強制的にリンクさせると正しい結果が得られました。
リンクされるライブラリのパスを表示するリンカオプションが分からなかったので、sysinternalsのFilemonユーティリティを用いて調べてみると、import32.libというファイルがリンクされていることが分かりました。tdumpで覗いてみると、

07A553 LEDATA Segment: (20314) '__LNan' Offset: 0000 Length: 0010
0000: 00 00 00 00 00 00 F8 FF 00 00 00 00 00 00 00 00 ................

やっぱりありました。シンボル重複が原因でした。
前述のとおり、xlvalues.objをリンクするか、cw32.lib(あるいは別のCRT-lib)をimport32.libより前にリンクすることで回避可能です。


なお、他にも同様のシンボルがこれだけありました。

__FDenorm
__FEps
__FInf
__FNan
__FSnan
__LDenorm
__LEps
__LInf
__LNan
__LSnan
__Denorm
__Eps
__Hugeval
__Inf
__Nan
__Rteps
__Snan

一応Quality Centralに報告済みです。