与-Weverything标志没有捕捉向量中不存在的元素

时间:2017-02-17 11:46:56

标签: c++ vector clang clang++ llvm-clang

我从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下没有包含这些标志?

1 个答案:

答案 0 :(得分:2)

philosopher[2] = 99;是合法代码,它使字符串成为1个字符的字符串,字符的代码为99.(可能是'c')。这似乎不直观,但std::string是几十年前设计的,现在它不能在不破坏现有代码的情况下进行更改。

该标准未指定vi[20000] = 44;所需的任何诊断。这是运行时未定义的行为;如果执行从未到达该行,则不会出错。

要捕获运行时错误,有一些选项,例如在调试器中运行,或使用clang的地址清理程序或valgrind。