0
int a[42]{};
std::cout << a[42];

std::string str(42, 'x');
std::cout << str[42];

Почему в первом случае срабатывает предупреждение о неопределенном поведении, а во втором нет?

fair
  • 3

2 Answers2

4

Для string доступ к элементу в позиции с индексом равным длине не ведет к неопределенному поведению.

Вот что говорит стандарт:

21.3.2.5 Element access[string.access]

constexpr const_reference operator[](size_type pos) const;
constexpr reference operator[](size_type pos);

  1. Preconditions: pos <= size().

  2. Returns: *(begin() + pos) if pos < size(). Otherwise, returns a reference to an object of type charT with value charT(), where modifying the object to any value other than charT() leads to undefined behavior.

  3. Throws: Nothing.

В следующем коде имеет место случай 2, а именно pos == size(), а тут поведение определено однозначно:

std::string str(42, 'x');
std::cout << str[42];
  • where modifying the object leads to undefined behavior. -> where modifying the object to any value other than charT()* leads to undefined behavior.* – вася Jul 02 '20 at 11:34
  • http://eel.is/c++draft/string.access, https://en.cppreference.com/w/cpp/string/basic_string/operator_at – вася Jul 02 '20 at 19:41
0

Потому что теоретически, у класса string квадратные скобки могут быть переопределены и запускать ракету на Марс.

gbg
  • 22,253
  • Если вдаваться в подробности безопасности исключений и работы контейнера, то есть резон знать почему именно так реализован оператор, а не иначе – AR Hovsepyan Jul 02 '20 at 11:58