2017-02-17 14 views
0

私はStroustrupのプログラミングの原則と実践からC++を学んでいます。clang with -Weverythingフラグがベクトル内に存在しない要素をキャッチしない

次のコードスニペット:のみ、このコンパイル時にエラーを与えて

#include "include/std_lib_facilities.h" 

int main() { 
    vector<int> v = { 5, 7, 9, 4, 6, 8 }; 
    vector<string> philosopher = { "Kant", "Plato", "Hume", "Kierkegaard" }; 

    philosopher[2] = 99; // compile-time error should be here, too 
    v[2] = "Hume";  // compile-time error presented here as it should 

    vector<int> vi(6); 
    vector<string> vs(4); 

    vi[20000] = 44; // run-time error, but not compile-time error 
    cout << "vi.size() == " << vi.size() << '\n'; 

    return 0; 
} 

clang++ -std=c++1z -g -Weverything -Werror -Wno-c++98-compat -Wno-c++98-compat-pedantic -Ofast -march=native -ffast-math src/055_vector.cpp -o bin/055_vector 
src/055_vector.cpp:11:7: error: assigning to 'int' from incompatible type 'const char [5]' 
     v[2] = "Hume";   // compile-time error presented here as it should 
      ^~~~~~~ 
1 error generated. 

私は-std=c++1z -g -Weverything -Werror -Wno-c++98-compat -Wno-c++98-compat-pedanticコマンドでエラーチェックを可能にしました。

philosopher[2] = 99; 
vi[20000] = 44; 

私が最初にコンソール出力からv[2] = "Hume";エラー行をコメントアウトし、私だけでコンパイルする場合:しかし、あなたはこれらの行はエラーを与えるが、本によると、これらは単にv[2] = "Hume";と同じように、また、すべきでない見ることができるようにvi[20000] = 44;ライン、それはさらに悪いことには問題なくコンパイルが、私がしようとした後、プログラムを実行します。

This application has requested the Runtime to terminate it in an unusual way. 
Please contact the application's support team for more information. 
terminate called after throwing an instance of 'Range_error' 
    what(): Range error: 20000 

ベクトルに存在しない要素をキャッチし、私はベクトルのintに文字列を代入しようとする場合には?これを含まない-Weverythingのように見えます。

-Weverythingの下に埋め込まれていないclangには、このケースの隠しフラグがありますか?

+3

コンパイラは、あらゆる種類のプログラミングエラーに対して警告またはエラーを出すことを義務付けられていません。 (実際には、コンパイラが診断を行うことを義務づけられているケースが標準で定義されています)。 「警告なし」は「プログラムの間違いなし」に等しくありません。 - 'vector :: operator []'はレンジチェックではないので、 'vector :: at()'を使ってください。 – DevSolar

答えて

2

philosopher[2] = 99;は正当なコードで、文字列を1文字の文字列にし、その文字のコードは99(おそらく'c')です。これは直感的ではないようですが、std::stringは数十年前に設計されましたが、現在は既存のコードを破ることなく変更することはできません。

標準ではvi[20000] = 44;に必要な診断は指定されていません。これは実行時に定義されていない動作です。実行が決してその行に到達しなければ、それは誤りではないでしょう。

ランタイムエラーを検出するには、デバッガでの実行や、clangのアドレスサニタイザ、valgrindなどのオプションがあります。

関連する問題