需要のないページ

プログラミングや趣味や。

定数M_PIが使えない

能書き

かなり間があいたので、小ネタ。

毎度ながら、知ってる人にとっては当たり前の内容を有難そうに書く。

 

遭遇したエラー

例えば、次のようなコードを書いたとする。

まあ、半径から円の面積を計算するだけの、よく見るコードだ。

 

ただし、円周率を自前で定義しているあたり、このコードはモダンでない。

_USE_MATH_DEFINESフラグを立ててcmathをインクルードしたほうがよい。

上記のコードのdefine文を単に置き換えると次のようになる。

しかし、このコードをコンパイルすると... 次のようなエラーが出る。

error C2065: 'M_PI': 定義されていない識別子です。
error C2065: 'M_PI': undeclared identifier

 

原因と対策

実はこれ、ヘッダファイルを読み込む順序が問題なのである。

エラーが出たコードでは、フラグを立てる前にiostreamを読み込んでいた。

 

iostreamヘッダのインクルードを追ってみると:

  • iostreamは、istreamをインクルードしている。
  • istreamは、ostreamをインクルードしている。
  • ostreamは、iosをインクルードしている。
  • iosは、xlocnumをインクルードしている。
  • xlocnumは、cmathをインクルードしている。

巡り巡って、iostreamをインクルードすると、cmathが読み込まれる。

もちろんその時点では_USE_MATH_DEFINESフラグは立っていない。

 

解決策は、次のとおり。

マクロの順序を変更しただけ。

ヘッダファイルに関するフラグは、include文より前に定義しよう。

 

雑記:前もって定義されている数学定数

#define _USE_MATH_DEFINES

フラグを立ててcmathをインクルードすると、次の数学定数を利用できる。

f:id:LouiS:20170506160658j:plain

ネイピア数含め対数周りの定数と、円周率に関する定数。

一番下の定数を、M_1_SQRT2と改名すべきと思うのは私だけだろうか?

 

雑記:ぼやき

iostreamに、cstdlibやcmathがインクルードされてるっていったい何なんだ。

いわゆる神モジュールになっている気が...