我从Stroustrup的编程原理与实践使用C ++学习C ++,第2版。
以下代码段:
#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
不包括此内容。
clang中是否有更严格的隐藏标志,-Weverything
下没有包含这些标志?
答案 0 :(得分:2)
philosopher[2] = 99;
是合法代码,它使字符串成为1个字符的字符串,字符的代码为99.(可能是'c'
)。这似乎不直观,但std::string
是几十年前设计的,现在它不能在不破坏现有代码的情况下进行更改。
该标准未指定vi[20000] = 44;
所需的任何诊断。这是运行时未定义的行为;如果执行从未到达该行,则不会出错。
要捕获运行时错误,有一些选项,例如在调试器中运行,或使用clang的地址清理程序或valgrind。