2013-11-12

C99の複素数ライブラリがクソすぎる。

C99では、複素数ライブラリが採用された。たとえば3.0 + 4.0iの複素数を書きたい場合、GNU拡張では、以下のように書く。

#include <complex.h>

double _Complex x = 3.0 + 4.0i ;

complex.hをincludeすれば使えるようになる。見た目はそのまんまだ。

これはGNU拡張であって、C99の規格による正式な書き方は以下の通りだ。

float _Complex x = 3.0 + 4.0 * _Complex_I ;

_Complex_Iは、"0+1i"を意味する虚数単位定数であり、にかければ任意の虚部を表現できる。あとは実部を足せばいい。

どうやら、C標準化委員会は、まともな名前を考えつかなかったらしい。まあ、大方のきれいな名前は、既存のソースコードと衝突してしまうから、アンダースコアに大文字で始まる予約語を使うしかないのだろう。

ただし、_Complex_Iのような汚い名前を書かせるのはどうかと思ったらしく、C標準化委員会のバカどもは、とんでもないマクロを標準で定義してしまった。

// complex.hのincludeによって宣言されるマクロ
#define I _Complex_I

// ユーザーのコード
3.0 + 4.0*I ; // OK

一文字マクロだと? 標準規格で?

アホかあいつらは。

最悪なことに、C++11はC99の標準ライブラリを取り込んでいるので、C++11でも、なんとcomplex.hをincludeすると、この恐ろしい一文字マクロまで宣言されてしまう。つまり、C++にもこの問題がやってくる。

ちなみに、このマクロはユーザー側でundefしても問題ないらしい。最初から入れるなボケ。

Complex Numbers - The GNU C Library

さすがに反省したらしく、C11では、この恐ろしい一文字マクロはoptional扱いになっているようだ。

ただ、GCCとClangではどういうわけか、独自拡張を許す-std=gnu++11ではなく、厳格に規格準拠にする-std=c++11すると、complex.hは使えるのだが、この一文字マクロだけは宣言されていない。不思議なこともあるものだ。

No comments: