WindowsでCLAPACKを使おう

やあ子供たち。もうすっかり秋も深まり、庭の柿の木になってる柿もすっかり刈り取り時期を迎えたよ。けど今年はあまり採れなかった。昨年は300個近くとれたのだけど今年は50個も採れてないんじゃないかな。
さあ今日はWindowsでCLAPACKを使う話だよ。それも、Win32APIやMFCを使う際に使用される各種ヘッダ群との共存をさせようと思ったときに知っておかなくちゃならないびっくり仰天事実の紹介だ。

まず、CLAPACK for Windows のヘッダとライブラリを取ってこよう。
http://icl.cs.utk.edu/lapack-for-windows/
(2020年8月22日追記:上記リンクでは64ビット版が得られないので、今日では、こちらのmomoseさんのサイトを参考にして、cmakeで自分でモジュール作ろう)
まずは空のプロジェクトを作成して、main.cpp を新規作成した中に以下のごとく、必要なヘッダの組み込みとライブラリのリンクのみする、最低限のCLAPACKプログラムをビルドしてみよう。CLAPACKといっても使用はしてなくてリンクだけしてるプログラムだね。

#include < iostream >

// clapack ヘッダ取り込みとライブラリのリンク
extern "C"{ // ⇐これはとても大事。VS2020 なんかではこれがないとリンクエラーになるぞ。
  #include "f2c.h"
  #include "clapack.h"
}
#pragma comment( lib, "blas.lib" );
#pragma comment( lib, "lapack.lib" );
#pragma comment( lib, "libf2c.lib" );
//

int main( void )
{  
  // __dgetrf とかここでもう使える状態。
  return 0;
}

さあ問題なくビルドできたね。これは問題ないんだね。そうそうこういう使い方なら問題ないからいいんだよ。誰も困らないね。
さて問題は、MFCアプリケーションなどで、同じことをやろうとした場合だよ。MFCアプリケーション、例えばSDIアプリケーションのプロジェクトを作成して、適当な.cppファイルの冒頭などに、上記の如く、CLAPACKのヘッダ組み込み&ライブラリリンクコードの記述して、ビルドしてみよう。
するとどうだ。

「C2144: 構文エラー: 'char'は')'によって先行されなければなりません」だと。こんなエラーが出て、どこが指摘されているのかと思えば、

あれ、CLAPACK.hの中?。
さてさてこの行を見て、どこか前後に記述された行と何か相違があるだろうか。doublerealというのはどこかでtypedefされた型名だろうし、それは前の行でも使われているしとくに問題はなさそうだ。と思ったりして、いろいろ検索して調べてみてもなかなか答えが見つからず、危うく迷宮入りしそうな様相を呈している。
結論から言うと、この場合は、small という変数名に原因があるんだね。このsmall という変数名をsmall1 と書き換えるだけで、ビルドは成功するようになるよ。

(slabad_()、dlabad_() という二つの関数において変数small の書き換えが必要だ)だがそれは原因がどこにあるかであって、問題そのもののありかではないんだ。つまりCLAPACKには何の罪もないわけさ。まー空のプロジェクトで使った場合には問題ないわけだからそう考えるのが当たり前だよな。
問題は、WindowsのシステムAPI系のヘッダのどこかで、char の別名として small というものが定義されていることなんだ。つまり、WindowsネイティブなAPIを使う開発環境においてはsmall という変数名は使うべきではないということなんだね。
はい、この話は以上で終わりだよ。MSの人たちにも是非読んでもらって、small についてはどうにかならないものか検討してほしところだね。まー今更変えられないっていう話なのだろうけどな。チョップだろチョップ。MSの人たちにチョップだねこんなあるまじき事態作り出しやがって!みたいなね。
ていうか今回のこれ、とくに困ってる人あまりいなさそうなあたり、CLAPACKをWindowsで使おうなんてやつはもしかするとあまりいないのかも知れない。ましてWindowsだったとしても、CLAPACKを主に使いたい研究畑の人たちは、Win32API直接叩いたり、MFC使おうなんて考える人はなおさらいないということがあるのかも知れない。研究畑の人たちはもしかしたらcygwinだとかmingwとか、キュートとかの方に流れる可能性が大きいからね。
それは違うぞということがあれば誰か教えてくれないか。じゃっ!