web-dev-qa-db-ja.com

max(a、b)はstdlib.hで定義されていますか?

2台のコンピューターを使用しており、それぞれに異なるバージョンのVisual Studioが使用されています。 Visual Studio 2008コンピューターで、コードがコンパイルされます。ビジュアル2010コンピューターでは、私の知る限りstdlib.hで定義されているマクロmax(a,b)を使用しているため、コードがコンパイルされません。 max(a,b)を定義することはできません。ビジュアル2008コンピューターでの再定義になるからです。しかし、max(a,b)を定義しないと、ビジュアル2010コンピューターでコードがコンパイルされません。

解決策はありますか?

20
snakile

標準ヘッダーにmaxという名前のマクロを定義するCライブラリは、想像を超えています。幸い、そのようなプラットフォームをサポートする必要がある場合の簡単な回避策は、システムヘッダーを含めた後、独自のヘッダー/コードの前に#undef max(およびそれが定義するその他の問題のあるマクロ)を実行することです。

他の誰もがあなたの定義を#ifndef max ... #endifで囲むように言っていることに注意してください。これはnotです。システムヘッダーでmaxを定義することは、実装者が無能であることを示しており、環境の特定のバージョンにマクロが正しくないマクロがある可能性があります(たとえば、かっこで引数を適切に保護していないものですが、maxではなくminを誤って実行しているmaxマクロも少なくとも1回は見ました。私の人生!)。 #undefを使用するだけで安全です。

stdlib.hmaxを定義するのがなぜうまくいかないのかについては、C標準は、アプリケーション用に予約されている名前、および標準関数や内部使用のために予約されている名前について非常に具体的です実装。これには十分な理由があります。アプリケーションプログラムで使用される変数/関数名と衝突する可能性のあるシステムヘッダーでマクロ名を定義することは危険です。最良の場合は明らかな原因を伴うコンパイル時エラーにつながりますが、それ以外の場合はデバッグが困難な非常に奇妙な動作を引き起こす可能性があります。いずれの場合も、ライブラリがすでにどのような名前をとるかがわからないため、移植可能なコードを書くのは非常に困難です。

31
R..

だからあなたの主な質問に答える:

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 */
5
Calmarius

_#ifndef_で保護します。

_#ifndef max
    #define max(a,b) ((a) > (b) ? (a) : (b))
#endif
_

上記のバージョンはインライン関数ほど安全ではないことに注意してください。 max(a++,b--)は予期しない結果を引き起こします。

3
John Ledbetter

条件コンパイルを使用できます。

#ifndef max
  #define max(a,b) ...
#endif
0
Vladimir Ivanov

Visual C++では、#define NOMINMAX標準ヘッダーを含める前に、マクロmaxまたはminを取得しません。

0
Bill Lynch