2006年9月15日金曜日

はて? これはバグ?

今、研究で信号処理のプログラムをC言語で書いている訳なんですが、ちょいと私の思っていたのと違う動作をしたコードがありました。
ハードウェア依存型のFFTライブラリを使っており、その関数に利用する係数変換行列を配列で用意しているんですが、FFTのサイズがもう決まっているので最初から宣言しておくことにしました。
で、色々な関数でFFT関数を使い回すのでグローバル変数として宣言。というか、その係数行列を作成するジェネレータがライブラリとともに配布されていたので、それを利用して計数行列を宣言したんですよね(そのジェネレータプログラムはCの文法で配列を生成してくれる)。作成された配列はconst宣言がされておりました。まーFFT中に回転行列の値が変わることはないだろうと思ってさして気にもしていなかったんです。
回転行列は
const float w[2 * 1024]=
{ ・・・・
};
って形で宣言されていたので、FFTを利用する別ファイルにて
extern const float w[2 * 1024];
と宣言した訳なんですね。そしたらなんとFFT関数の方が引数にconstがついておらず、型が一致しませんというエラーが。
なんでFFT関数を作ったメーカーの作成したジェネレータで用意した回転行列にconstついてるのに使えねーんだと思いつつ、
extern float w[2 * 1024];
と宣言したらコンパイル通っちゃいました^^; まぁFFT関数実行前と実行後で回転行列の値をチェックしてみましたが、変更された形跡はなかったのでまぁ特に困ることもなかったわけですが、気持ちは悪いですよねぇ・・・。
で、ここで気になることが。元々宣言したところではconst修飾子が付いているためにこの配列の値を変更することは不可能ですが、extern宣言している方ではconst修飾子をつけていないため、値を変更しようとするコードを書いていても、コンパイルエラーは出ないのではないか。
で、試してみたところ、やっぱりエラーは出ませんでした・・・。おまけに中身書き換えられてたし!
それって、Cの仕様として果たして正しいんだろうか・・・。それともバグかしら。確かこのコンパイラはANSI/C準拠だったと思うんだけどなぁ・・・。
それとも配列へのconstはポインタが書き換えられないようになっているだけで中身の保護はまた違う書き方をしないといけなかったっけなぁ・・・。なんかそのルールは見覚えがあるけれど、今ひとつはっきりと思い出せない・・・。
まー今はそれの検証をしている余裕はないので放置ですが、ちょっと気持ち悪い^^; Cってパワフル過ぎるんだよなぁ・・・。けどハードウェアへの実装だからCじゃなきゃアセンブラで組めって言われるし、そりゃとてもじゃないけれど無理だ;;
とりあえず早くバグを取り除いて結果を出したいー!!!><
ただいま激しく迷走中w

1 件のコメント: