2台のコンピューターを使用しており、それぞれに異なるバージョンのVisual Studioが使用されています。 Visual Studio 2008コンピューターで、コードがコンパイルされます。ビジュアル2010コンピューターでは、私の知る限りstdlib.hで定義されているマクロmax(a,b)
を使用しているため、コードがコンパイルされません。 max(a,b)
を定義することはできません。ビジュアル2008コンピューターでの再定義になるからです。しかし、max(a,b)
を定義しないと、ビジュアル2010コンピューターでコードがコンパイルされません。
解決策はありますか?
標準ヘッダーにmax
という名前のマクロを定義するCライブラリは、想像を超えています。幸い、そのようなプラットフォームをサポートする必要がある場合の簡単な回避策は、システムヘッダーを含めた後、独自のヘッダー/コードの前に#undef max
(およびそれが定義するその他の問題のあるマクロ)を実行することです。
他の誰もがあなたの定義を#ifndef max ... #endif
で囲むように言っていることに注意してください。これはnotです。システムヘッダーでmax
を定義することは、実装者が無能であることを示しており、環境の特定のバージョンにマクロが正しくないマクロがある可能性があります(たとえば、かっこで引数を適切に保護していないものですが、max
ではなくmin
を誤って実行しているmax
マクロも少なくとも1回は見ました。私の人生!)。 #undef
を使用するだけで安全です。
stdlib.h
がmax
を定義するのがなぜうまくいかないのかについては、C標準は、アプリケーション用に予約されている名前、および標準関数や内部使用のために予約されている名前について非常に具体的です実装。これには十分な理由があります。アプリケーションプログラムで使用される変数/関数名と衝突する可能性のあるシステムヘッダーでマクロ名を定義することは危険です。最良の場合は明らかな原因を伴うコンパイル時エラーにつながりますが、それ以外の場合はデバッグが困難な非常に奇妙な動作を引き起こす可能性があります。いずれの場合も、ライブラリがすでにどのような名前をとるかがわからないため、移植可能なコードを書くのは非常に困難です。
だからあなたの主な質問に答える:
Max(a、b)はstdlib.hで定義されていますか?
いいえ、そうではありません。windef.hの187行目で定義されています。
#ifndef NOMINMAX #ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) #endif #ifndef min #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif #endif /* NOMINMAX */
_#ifndef
_で保護します。
_#ifndef max
#define max(a,b) ((a) > (b) ? (a) : (b))
#endif
_
上記のバージョンはインライン関数ほど安全ではないことに注意してください。 max(a++,b--)
は予期しない結果を引き起こします。
条件コンパイルを使用できます。
#ifndef max
#define max(a,b) ...
#endif
Visual C++では、#define NOMINMAX
標準ヘッダーを含める前に、マクロmax
またはmin
を取得しません。