続・HAVE_INFINITY

発端は

% make
...
compiling ../trunk/numeric.c
"/usr/include/math.h", line 73.9: 1506-236 (W) マクロ名 INFINITY が再定義されています。
"/usr/include/math.h", line 73.9: 1506-358 (I) 「INFINITY」が ../trunk/include/ruby/missing.h の 139 行目に定義されてい ます。
"/usr/include/math.h", line 74.9: 1506-236 (W) マクロ名 NAN が再定義されています。
"/usr/include/math.h", line 74.9: 1506-358 (I) 「NAN」が ../trunk/include/ruby/missing.h の 147 行目に定義されています。

を消そうというところからでした。現状でgccではでてこないですが、xlcだとでてきました。gccでは同じファイルでの再定義はwarningくれましたが、ファイルが分かれるとwarningくれないみたいです。xlcで使う人なんていない気がするので、このメッセージ見る人多分いないとは思いますが。ほかに、bignum.c、complex.c、などででます。

で、numeric.cでいうと、

...
    12  #include "ruby/ruby.h"
...
    17  #include <math.h>
...

で、math.hはあとからincludeされるようになっています。その前のruby.hのなかでincludeされるmissing.hのなかの

   127  #if !defined(INFINITY) || !defined(NAN)
   128  union bytesequence4_or_float {
   129    unsigned char bytesequence[4];
   130    float float_value;
   131  };
   132  #endif
   133
   134  #ifdef INFINITY
   135  # define HAVE_INFINITY
   136  #else
   137  /** @internal */
   138  RUBY_EXTERN const union bytesequence4_or_float rb_infinity;
   139  # define INFINITY (rb_infinity.float_value)
   140  #endif
   141
   142  #ifdef NAN
   143  # define HAVE_NAN
   144  #else
   145  /** @internal */
   146  RUBY_EXTERN const union bytesequence4_or_float rb_nan;
   147  # define NAN (rb_nan.float_value)
   148  #endif

がmath.hより先にくるんで、この時点ではINITINITYがないことになっているようです。が、あとからmath.hでINFINITYが再定義されるので、実際にはそっちが使われています。gcc -Eやxlc -Eで確認。なので、動作に支障はないと思っています。しいて言えば、使わないrb_infinityが残っていることでしょうか。-Wunused-variablesはGlobal変数には効かないんですね。ほかのファイルからつつかれるかもしれないからでしょうか。

で、これは手元のLinuxでも同じ(使わないrb_infinityが残っている)なので、意図的なのかどうかわからないのと、メッセージ消したい私としてはどうけりをつけようかなと思案中です。

math.hのincludeを手前に持ってくると、xlcでは何かもっとほかの事が起きる、gccでは想定どおり先にincludeされない、という。何か根本的に間違えている気がしないでもないです。

あ、なるほど。gccでは-include ruby/missing.hがファイルの内容より先にincludeされているんですね。

config.hにチェックしてHAVE_INFINITYとHAVE_NANを加えたとしても、missing.hの内容的には、INFINITYやNANがなきゃ意味ないな。

手詰まり感でいっぱいです。誰も困っていない問題(?)をソリューションなしにMLに投げるのは大変ためらわれます。さて、どうしたものか。