2011-10-24 8 views
5

私はこの非常に単純なコードを持っています。MSVCC/g ++/iccのstd deque/vectorの動作が異なります

#include <deque> 
#include <vector> 

using namespace std; 

class A 
{ 
public: 
    A(){}; 
    ~A(){}; 
    deque<A> my_array; // vector<A> my_array; 
}; 

int main(void) 
{ 
} 

私はLinux上でg ++およびICC/ICPCの両方で、このコードをコンパイルした場合、それは何の警告を与えなくても-Wallと、罰金コンパイル。両端キューをベクトルに入れ替えると、状況は同じです。

私はMSVCC(CL)を使用してWindows上でこのコードをビルドしたいと思いますが、残念ながら、それはエラーC2027をスロー:

error C2027: use of undefined type 'A' 

しかし、私はそれは、Visual Studio 2010

と罰金コンパイル std::vectorstd::dequeを変更した場合

私の質問は、何らかの理由でこの動作が予想されるのでしょうか?もしそうなら、なぜコンパイラ間に違いがあるのですか、これはg ++/iccまたはMSVCCの間違いでしょうか?

答えて

12

それは、std::dequeとし、std::vectorとの両方(未定義の動作です ので、実装はそれでないものは何でも限り 標準に関しては、結構です。あなたは 不完全な型で標準コンテナをインスタンス化している。

唯一の懸念言語のG ++、-Wallでコンパイル(と一般的には、すべてのオプションが-Wと を開始)。ライブラリの問題について、あなたは 同様-D_GLIBCXX_CONCEPT_CHECKS -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTICでコンパイルする必要があります。(これは、パフォーマンス 問題が発生した場合は、削除することができます最後のt )

+0

+1しかし、私は 'deque'だけのUBであることを期待していました。 – iammilind

+0

"標準が関係している限り、どのような実装でも問題ありません" - 準拠している実装では、定義されていない動作があるからといってコンパイルに失敗してはいけません。もちろん、診断を与えることはできますが、その診断がただの警告である準拠モードに実装を置くことは、あまり目立たないことがあります。 –

+0

@SteveJessop標準 (§1.3.12)の_undefinedビヘイビア_の定義は、「この国際規格では **の**要件はありません」(明示的に追加)を明示しています。直後の の注記では、 の実装の例として、[**翻訳**を終了するための[...]または診断メッセージの発行( との実行)を示しています。 –

0

さらに、James Kanzeの答えを検索したところ、不完全な型のコンテナを使用する標準の姿勢を説明しているthis Dr Dobbs articleが見つかりました。

さらに、それはvectorsで動作する理由、つまりdequeではないことを示唆しています。つまり実装です。典型的なベクターは、私たちがTへのポインタのみを持っていますが、dequeはうまくそれが値でTを使用すること(VS2010で)ような方法で実施することができるので、不完全型で大丈夫です

class vector<T> { 
    T* buff; 
    int size; 
    // ... snip 
}; 

のようなものかもしれ不完全な型と互換性がなくなります。

関連する問題