2

この質問は、次のいずれとも同じではありません。

私は Windows 7 と Visual Studio Express 2012 を実行していますが、どちらもこの質問への回答に影響を与えることはないと思います。

tl;dr 次の math.h からの抜粋の影響を最も適切に打ち消す/防止する/許容する方法を教えてください。

#if     !__STDC__

/* Non-ANSI names for compatibility */

#define DOMAIN      _DOMAIN
#define SING        _SING
#define OVERFLOW    _OVERFLOW
#define UNDERFLOW   _UNDERFLOW
#define TLOSS       _TLOSS
#define PLOSS       _PLOSS

#define matherr     _matherr

背景: 私は趣味のテキストベースの C++ プロジェクトを書いていますが、その全体的な目標はこの質問の範囲をはるかに超えています。私はGNU Makeを使用して(親しみやすさと移植性のために)Cygwin g ++とcl.exeの両方でコンパイルし、厳密に標準に準拠した環境を想定しています...これまでのところ。私は、Windows がそのような想定を単に許可していないと考え始めています。

メンバーにOVERFLOWandが含まれる列挙型がありUNDERFLOWます。以下に説明する問題により、これらの名前を変更せざるを得なくなる恐れがありますが、Windows ヘッダー ファイルなどの外部の影響にもかかわらず、私の目的に最も適しているため、そのままにしておくことをお勧めします。

GCC、Visual C++、および Mac OS X のヘッダー ファイル (llvm-gcc とは無関係) はすべて、デフォルトで math.h で、他の非標準マクロの中でOVERFLOWおよびを定義します。UNDERFLOW

  • GCCにはこれらの定義を完全に防止するための文書化された手段がいくつかあります。
  • Mac OS X には、同じことを行う文書化されていない方法がいくつかあります。そのうちの 1 つ ( _POSIX_C_SOURCE) は、GCC のドキュメントと一致しています。(Apple のドキュメントの不足を補うためにこれについて言及します。私はこれらの識別子の歴史を持っています。)
  • MSDNは、Visual C++ でいくつかの非標準マクロの定義を防止する (マクロを介した) 手段として、/u コマンド ライン オプションを文書化しています。この質問の冒頭で示したように、マクロはとの定義防ぎます。__STDC__ __STDC__OVERFLOWUNDERFLOW

/u スイッチを使用すると、懸念していた定義が妨げられることがわかったので、それをメイクファイルに追加しました。しかし、crtdefs.h の 44 行目から新しいエラーが発生しました。

error C1189: Only Win32 target supported!

これは、_WIN32が定義されなくなったためです。少し検索したところ、crtdefs.h が Windows Driver Development Kit に関連していることがわかりました。私はドライバーを開発していません。どういうわけかそのヘッダーを使用しないことはできますか? または、非標準の Windows の動作を許容するために、列挙型メンバーの名前を変更する必要がありますか?

4

3 に答える 3

1

2つの可能性が思い浮かびます。

math.h1つ目は、次のように、を含めるたびに特定の効果を元に戻すようにすることです。

#include <math.h>
#undef OVERFLOW
#undef UNDERFLOW

さて、それはまた、それらのものが適切に定義されることを期待するコードのどこかで問題を引き起こす可能性があります。ただし、その場合でも、ソフトウェアを変更して、次の名前に別の名前を使用することができますmath.h

#include <math.h>
#undef OVERFLOW
#undef UNDERFLOW
#define MATH_H_OVERFLOW  _OVERFLOW
#define MATH_H_UNDERFLOW _UNDERFLOW

それらを使用したいすべてのソースコード(ライブラリのようなコンパイル済みのコードは重要ではありません)がmath.h、列挙内の定数の代わりに定数を使用することを確認する必要があります。MATH_H_*


enum2つ目は、メンバーの名前を競合しないものに変更するのにかかる労力と比較して、このクエストに費やす労力の量について非常に慎重に考えることです。両方にまったく同じ量の情報が残っているOverflowため、(の代わりに)列挙に使用するようなものが私の最初の試みであり、すぐに競合が解消されます。OVERFLOW

はい、それを伴わない方法を見つけるのは良いことですが、環境でマイナーな問題を回避するために膨大な時間を費やすのではなく、ソフトウェアを提供するビジネスに従事する必要があります:-)

于 2012-09-18T02:32:14.073 に答える
1

複数の効果/uを持つコンパイラ スイッチを使用する代わりに、これを使用してマクロを定義し、それ以外は何も使用しません。/D__STDC__=1__STDC__

于 2012-09-18T04:15:40.097 に答える
0

C++11 では、スコープ付き列挙型を使用できます。

enum class Flows { Underflow, Overflow };

Flows::Underflow と Flows::Overflow を参照するようになりました。

C++98 でも、クラスでこれをシミュレートすることをお勧めします。

class Flows
{
public:
    enum Value { Underflow, Overflow };
};
于 2012-09-18T03:24:37.403 に答える