View in Telegram
Ответ На самом деле в код выше я упустил оператор delete[], поэтому в нем есть утечка памяти. Этого я не учел, так как на другом концентировался. Моя ошибка, но соль примера была в другом. Поэтому сейчас будем разбирать такой код:
#include <iostream>

int main() {
  auto array = new int[10, 20]{10};
  std::cout << array[1, 0] << " " << array[11, 1] << std::endl;
  delete[] array;
}
Такой код соберется выведет на консоль "10 0" и успешно завершится. Но то, что код успешно завершается не значит, что он понятен и работает, как мы ожидаем. Основная загвоздка в том, что в С++ запятая - это не просто знак препинания. Это оператор! У него есть вполне четкое и прописанное поведение - он игнорирует результат любого выражения, кроме последнего. То есть
Expression1, Expression2, Expression3
Все выражения вычислятся, но результатом комбинированного выражения будет результат Expression3. Поэтому когда мы пишем [i, j] до с++23, то это полностью эквивалентно [j]. Компилятор видит несколько параметров в [] и, так как сам оператор индексации не принимает несколько параметров, то выход только один - парсить через оператор запятая. Получается, что с помощью new int[10, 20] мы создали одномерный массив на 20 элементов. Ну и вообще, весь код полностью эквивалентен следующему:
#include <iostream>

int main() {
  auto array = new int[20]{10};
  std::cout << array[0] << " " << array[1] << std::endl;
  delete[] array;
}
На самом деле компилятор умеет выдавать предупреждения на использование оператора запятая. Поэтому использовании флагов компиляции -Werror -Wall, которые разрешают предупреждения и превращают их в ошибки компиляции, сборка упадет. Так что первый вариант ответа тоже был верным с какой-то стороны. Теперь, почему 10 0. При аггрегированной инициализации мы можем в фигурных скобках указывать меньше элементов, чем может поместиться в массив или структуру. При этом остальные элементов будут инициализироваться так, как если бы они инициализировались от пустых скобок(аля array_elem = {};). Для интов это значит, что все элементы, кроме первого будут иметь нулевое значение. То есть, никакого мусора. При использовании аггрегированной инициализации все поля будут иметь корректное и понятное значение. Вот такая противная запятая. Don't be confused. Stay cool. #cpp23 #cppcore
Love Center - Dating, Friends & Matches, NY, LA, Dubai, Global
Love Center - Dating, Friends & Matches, NY, LA, Dubai, Global
Find friends or serious relationships easily