cpp-ru / ideas

Идеи по улучшению языка C++ для обсуждения
https://cpp-ru.github.io/proposals
Creative Commons Zero v1.0 Universal
89 stars 0 forks source link

Добавить в std::runtime_error и std::logic_error (и их наследников) конструктор, который получает std::string_view #508

Open eao197 opened 2 years ago

eao197 commented 2 years ago

Судя по документации на cppreference и по драфту стандарта (раздел 19.2) у std::runtime_error и std::logic_error есть конструкторы, которые получают const std::string& и const char * (при этом подразумевается, что const char* -- это строка с 0-символом в конце). Но нет конструктора, который бы получал std::string_view.

После добавления в стандарт std::string_view выглядит странно, что стандартные классы исключений не могут получать описание ошибки в виде std::string_view.

Отсутствие такого конструктора создает неудобства, например, в таких случаях:

// Throws an exception if operation can't be started.
void ensure_valid_state_for_operation(std::string_view operation_description) {
  if(!check_first_condition()) throw std::runtime_error{operation_description};
  if(!check_second_condition()) throw std::runtime_error{operation_description};
  ...
}

Такой код не скомпилируется. Нужно будет делать преобразование из string_view в string, но при этом мы можем получить две аллокации: первая при создании временного string, вторая -- при создании еще одной копии внутри runtime/logic_error (т.к. string принимается по константной ссылке и содержимое временного string-а не может быть перемещено внутрь runtime/logic_error).

pavelkryukov commented 2 years ago

выглядит странно, что стандартные классы исключений не могут получать описание ошибки в виде std::string_view.

Да, но обычно описание ошибки генерируют в рантайме, чтобы иметь в нём информацию для отладки; тут как раз подходит ссылка на std::string.

eao197 commented 2 years ago

Да, но обычно описание ошибки генерируют в рантайме,

Это далеко не всегда так. Бывают случаи когда проверяются аргументы функции/метода:

void do_something(const some_type * target, int retries) {
  if(!target) throw_invalid_parameter_exception("target can't be null");
  if(retries < -10 || retries > 15) throw_invalid_parameter_exception("retries is out of allowed range [-10, 15]");
  ...
} 

Раз уж в C++ добавили std::string_view, то было бы хорошо иметь возможность отказаться от использования const char * в том числе и при выбрасывании runtime/logic_error.

чтобы иметь в нём информацию для отладки; тут как раз подходит ссылка на std::string.

Даже когда описание исключения генерируется автоматически, то далеко не всегда это происходит через std::string. Описание может быть помещено внутрь какого-то std::array<char, 256> на стеке. И при формировании описания необязательно будет использоваться sprintf, который добавляет 0-символ в конце. Так что в этом std::array может тупо не быть 0-символа, необходимого для передачи описания в runtime/logic_error в виде const char*.

pavelkryukov commented 2 years ago

в #263 есть ссылка на предложение P0506

eao197 commented 2 years ago

в https://github.com/cpp-ru/ideas/issues/263 есть ссылка на предложение 0506

Я так понимаю, что судьба этого предложения печальна. Раз с 2017-го года никаких подвижек нет.

pavelkryukov commented 2 years ago

Я так понимаю, что судьба этого предложения печальна. Раз с 2017-го года никаких подвижек нет.

P0506 более агрессивное:

eao197 commented 2 years ago

По факту стандартные исключения не могут получать std::string_view, хотя это было бы полезно. И логично, раз уж в C++17 добавили этот самый std::string_view.