2017-02-17 21 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。