2013-08-08 8 views
6

Mingw 4.7.2では、isnanへの呼び出しのためにコンパイルされないライブラリがあります。 std::isnanを使用すると、コンパイラは「すべては問題ありません」と言いますが、実際にファイルをコンパイルできます。isdanはstd :: namespaceにありますか?もっと一般的には、std ::が必須か、オプションか、避けたいのですか?

しかし、私はhere編集:を多分私もhere :-)をチェックしている必要があります)チェックすると、std::は必要ではないようです。ファイルを追加すると、ファイルは移植可能になりますか?

さらに一般的には、std::が必要な場合(ポータビリティのために)、オプションであるか避けるべきかを理解する一般的な方法がありますか?

編集問題の起源の間で実際

は、複数のヘッダ介在物が存在することであり、このCPPファイルが<cmath>が既に含まれている場合(<math.h>を含むしようとしながら、付属のヘッダのいくつかは、<cmath>を含みます)。

+1

[ここ](http://en.cppreference.com/w/cpp/numeric/math/isnan)にチェックを入れないでください。 –

+0

@ChristianRau基本的にC++ 98ではこれは存在しませんでしたが、Cから借用するだけでそれを持つことができました!それは面白い! – Antonio

+0

いいえ、いつも通りです。このリンクは、関数名の前に大きな 'std ::'があることを示すだけです。偶然にも、特定の関数isnanはC++ 11でしかサポートされておらず、C++ 98には全く存在しませんでした(CヘッダでもC89/90ヘッダであってC++ 11が使用する)。ですから、CからCを借りることができますが、C++に含まれているCではなく、実際のC99から借りることができます(それは奇妙なミックスでなければなりません)。 –

答えて

12

どのヘッダーを含むかによって異なります。 Cヘッダに<math.h>(C++の一部ですが、非推奨とマークされていますが)を含めると、isnanのような非修飾C関数を使用できます。もし一方がC++ヘッダー<cmath>が含まれている場合、あなたはそれがstd名前空間に<math.h>からのすべての機能をもたらしますので、あなたがstd::isnanのように、それらを適切に修飾する必要が(またはusingディレクティブのいくつかの種類を使用する)ことをのみ保証されています。C++と理由の -incidences残念ながら実装は<cmath>含むときしかしは、あまりにも、グローバル名前空間にこれらの機能をもたらすためにを必要としない許可されている(したがって、それは多くのの一つである「私のマシン上で動作します」なぜあなたが失敗したようにコンパイルしようとしたかのように多くの人がコードを書いています)。だから、総括する

:どちらか一方が<math.h>を含めるとisnanを使用するか、<cmath>を含めるとstd::isnanを使用し、他のすべては非ポータブルです。もちろん、これは他のCヘッダとそれぞれのC++バージョンにも当てはまります。

EDIT:それは、この特定の機能isnanが唯一のC++ 11以降でサポートして(あなたの混乱の一部であるかもしれない)すべてのC++ 98で利用できなかったことにされて、しかし注意すべきです。しかし、C++ 98では<cmath>でも<math.h>でもなく、実際にはC99/C90ヘッダーで、C++ヘッダーではなくC99ヘッダーではないため、この機能はありませんでした。常に同期しています。だからあなたの質問からこのライブラリを試してみたのは、C90実装のC90/C90の部分と衝突する可能性があるので、別のC99実装からisnan関数を取ってC++ 98を使うことでした。 、これも試みたことはありません)。

+0

だからは推奨されていません! C++ 98では、しか使用しないでください。 C++ 98とC++ 11の両方で動作するコードを作成することは可能でしょうか? – Antonio

+0

@Antonioこの全体的な問題は、C++ 98とC++ 11とは関係ありません。 C++の標準が何であっても、私の答えにはいつも同じように記述されています。そして、ええ、Cのヘッダーは廃止と呼ばれていますが、実際にはあまり意味がありません。あなたが使っているのはむしろ味の問題です(私は自分自身のために、非常にアンチCのスノーとスパムの大ファンです'std ::'は全面的に、C++ヘッダーを好む)。しかし、もちろん一貫性を保つ必要があります。そうでなければ、あなたは実際にそうしたようにそのような感覚を経験します。 –

+0

[これはあなたのコメントの前に書かれました]上記のChristian Rauのコメント/リンクを見てください:isnan of ''はC++ 98には存在しないはずです...そしてC++ 98の唯一のisnanは廃止された ''は 'std ::'なしで呼び出さなければなりません。だから、ポータブルなのは...不可能なことです。いくつかの面倒な条件コンパイルをしない限りです。 – Antonio

2

これは、isnanがCから来たからです。異なるタイプのincludeを使用すると、異なる結果につながります。一例として、Cヘッダ<math.h>からisnanしてください:

あなたが#include <cmath>を使用している場合、それはstd名前空間に置かれます。

#include <math.h>を使用すると、グローバル名前空間に配置されます。フォーム名.hの名称をそれぞれ有する

C++ 11 D.5 C標準ライブラリヘッダ

すべてのCヘッダは、によって標準ライブラリの名前空間に配置されたそれぞれの名前かのように振る舞います対応するcnameヘッダーはグローバル名前空間スコープ内に配置されます。これらの名前が名前空間stdの名前空間スコープ(3.3.6)内で最初に宣言されるか定義されるかは明示されておらず、明示的なusing-declarations(7.3.3)によってグローバル名前空間スコープに注入される。

[例:ヘッダーは、確実に宣言と定義をネームスペースstd内に提供します。グローバルネームスペース内でこれらの名前を提供することもできます。ヘッダーは、C標準と同様に、グローバルな名前空間内で同じ宣言と定義を確実に提供します。名前空間std内でこれらの名前を提供することもできます。 -end example]

5

Cには名前空間の概念がありません。 #include <math.h>と書くと、ヘッダに宣言されているすべての名前がグローバル名前空間に入り、isnanと書く必要があります。

C++には名前空間があります。それでも、あなたはヘッダで宣言さ#include <math.h>すべての名前を書くときに、グローバル名前空間に入ると、あなたは、ヘッダー行く中で宣言#include <cmath>すべての名前を書くとき、あなたは、ちょうどまたC.

のように、isnanを記述する必要があります名前空間stdに入力し、std::isnanと記述する必要があります。

さらに、C++の実装はもグローバル名前空間にstdなどに名前を入れて#include <math.h>で、他の道を行くことを許され、そして#include <cmath>グローバル名前空間に名前を入れるだけでなく、ですstdに設定します。これに頼らないでください。コードは移植性がありません。これは、実装を簡単にするための譲歩です。実際には、#include <cmath>を使用する場合、グローバル名前空間にisnanが存在しないと仮定することはできません。#include <math.h>を使用する場合、がstdにないと想定できません。

+0

それで* both *を含めるとどうなりますか? (この具体的な例を見ると、私は矛盾した振る舞いをするつもりです) – Antonio

+2

@Antonioそれは、おそらく彼らの受注のインクルード注文とインクルードガードに依存します。要するに、*これを行うことはありません*。 –

+0

@ChristianRauありがとう、私はちょうど正式な答えが必要でした:)(私は図書館の作家ではありません) – Antonio

関連する問題