私はmath.h
を使用しているRubyのC拡張を書いています。 OSXとWindowsの両方でコンパイルされています。 Windowsでは、Visual Studio Express C++ 2010に付属のnmake
を使用します。Cで定義されていない関数を定義するには?
math.h
には、VSにround()
関数が含まれていませんでした。だから私は補うためにこれを追加しました:
static inline double round(double value)
{
return floor(value + 0.5);
}
そこが定義されているround()
としてOSXの下でコンパイルするときにコースを外れ、エラーの原因となりました。 (私が思う実際のエラーは、それがすでに非静的バージョンと宣言されていた後、私は私が静的宣言のだということでした。
かかわらず、私はそれが存在しない場合、この関数を再定義しないようにしたいと思います。
で。私は、これは条件付きの持っている瞬間:?私のシナリオで働いていた
#ifdef _WIN32
static inline double round(double value)
{
return floor(value + 0.5);
}
#endif
- しかし、それは少し一般的なようで、私が意味する、私はWindowsで別のコンパイラでコンパイルした場合にどのような
だから私の質問は、関数が既に定義されているかどうかを検出できますか?自分でそれを定義しないでください?
かは、私が特にコンパイラnmake
使用を検出することができます - 私はそれだと思うcl
?
私はそれが最も堅牢な方法のように見えるように私は、理想的には、関数がすでに定義されているかどうかを検出することができるだろうと思っています。しかし、それは少し一般的なようだ - 私のシナリオで働いていた
私が懸念していたのは、例えば私がVisual Studioを更新し、 'math.h'に' round() 'を含めた場合、OSXのような競合が発生するということでした。だから私は環境の代わりに機能をチェックする方が良い考えだと思っていたのです。これは、ユーザーエージェントの文字列を盗聴するのではなく、機能をテストするウェブ開発の考え方です。 – thomthom
@thomthom:ええ、でもこれはウェブ開発=)。これは、一般的なやり方です。コンパイラを変更するとブレークして修正する必要がありますが、ほとんどの場合は避けることができます。この場合、C99に 'round 'が追加されました。 VSはC99をサポートしていないため、C99は存在しません。 –
GNUのautoconfは、機能ベースのアプローチを使用して、#HAVE_featureという形式の定数を定義しています。例えば、あなたは 'HAVE_ROUND'を定義するかもしれません。この場合はコンパイラに依存するため、コンパイルコマンドのCプリプロセッサ定義で "-DHAVE_ROUND = 0"を実行できます。 round()を持つコンパイラの下では未定義のままにしておきます。 round()関数のラッパーは、#if defined(HAVE_ROUND)&&!HAVE_ROUND ... function declaration ... #endif'を読み込みます。 –