2017-02-17 53 views
0

我正在學習C++從Stroustrup的編程原則和實踐使用C++,第二版的書。鏗鏘與-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命令檢查。但正如你所看到的這些行不給錯誤,但根據書中,這也應該,就像v[2] = "Hume";

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

如果我註釋掉從第一控制檯輸出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下?

+3

編譯器沒有*義務*給每種編程錯誤提供警告或錯誤。 (實際上,標準中定義了編譯器有義務提供診斷的情況。)請考慮提供幫助。 「沒有警告」並不等於「程序中沒有錯誤」。 - 'vector :: operator []'不是範圍檢查,爲此使用'vector :: at()'。 – DevSolar

回答

2

philosopher[2] = 99;是合法代碼,它使字符串爲1個字符的字符串,並且該字符的代碼爲99(可能爲'c')。這似乎很不直觀,但std::string是幾十年前設計的,現在不破壞現有代碼就無法更改。

該標準未指定任何所需的診斷vi[20000] = 44;。這是運行時未定義的行爲;如果執行永遠不會到達那一行,那不會是一個錯誤。

要捕捉運行時錯誤,可以使用一些選項,例如在調試器中運行,或使用clang的地址清理程序或valgrind。