0

I'm learning C++ from Stroustrup's Programming Principles and Practice Using C++, 2nd Edition book.

The following code snippet:

#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;
}

Only giving this compile-time error:

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.

I enabled error checking with -std=c++1z -g -Weverything -Werror -Wno-c++98-compat -Wno-c++98-compat-pedantic commands. But as you can see these lines not giving errors but according to the book, these should also, just like v[2] = "Hume";:

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

If I commenting out the v[2] = "Hume"; error line from the first console output and I only compile with the vi[20000] = 44; line, it even worse, it compiles without problem, but after when I try run the program:

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

How to catch nonexistent elements in vector and if I trying to assign a string to an int in a vector? Looks like -Weverything not including this.

Are there any more strict hidden flags for this case in clang, which not inluded under -Weverything?

Lanti
  • 2,299
  • 2
  • 36
  • 69
  • 3
    A compiler is not *obliged* to give warnings or errors for every kind of programming error. (Actually, the cases in which a compiler is *obliged* to give a diagnosis are defined in the standard.) Consider warnings a helping hand. "No warnings" does not equal "no mistakes in the program". -- `vector::operator[]` is not range-checking, use `vector::at()` for that. – DevSolar Feb 17 '17 at 11:50

1 Answers1

2

philosopher[2] = 99; is legal code, it makes the string be a 1-character string and the character has code 99. (probably 'c'). This seems unintuitive, but std::string was designed decades ago and now it can't be changed without breaking existing code.

The standard does not specify any required diagnostic for vi[20000] = 44;. This is runtime undefined behaviour; if execution never reached that line, it would not be an error.

To catch runtime-errors there are some options, such as running in a debugger, or using clang's address sanitizer, or valgrind.

M.M
  • 138,810
  • 21
  • 208
  • 365