2017-02-17 29 views
0

Я изучаю C++ из принципов и практики программирования Страустрапа, используя книгу C++, 2-е издание.clang with -Wevery flag не улавливает несуществующие элементы в векторе

Следующий фрагмент кода:

#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 

Как поймать несуществующие элементы в векторе, и если я пытаюсь присвоить строку в междунар в векторе? Похоже -Weverything не включая это.

Есть ли более строгие скрытые флаги для этого случая в clang, которые не включены в число -Weverything?

+3

Компилятор не обязателен, чтобы давать предупреждения или ошибки для всех ошибок программирования. (Фактически, случаи, когда компилятор * обязан * давать диагноз, определены в стандарте.) Учитывайте предупреждения рукой помощи. «Без предупреждений» не равно «никаких ошибок в программе». - 'vector :: operator []' не проверяет диапазон, для этого используйте 'vector :: at()'. – DevSolar

ответ

2

philosopher[2] = 99; - это юридический код, он делает строку 1-символьной строкой, а символ имеет код 99. (возможно, 'c'). Это кажется неинтуитивным, но std::string был разработан несколько десятилетий назад, и теперь он не может быть изменен без нарушения существующего кода.

В стандарте не указывается какая-либо необходимая диагностика для vi[20000] = 44;. Это неопределенное поведение во время выполнения; если выполнение никогда не достигало этой строки, это не было бы ошибкой.

Чтобы уловить ошибки во время выполнения, есть некоторые параметры, такие как запуск в отладчике или использование дезинфицирующего средства для адреса clang или valgrind.