Достаем элемент из последовательного контейнера
Обработка ошибок, да и в принципе нежелательных путей развития ситуации, может порождать много споров, боли, баттхерта и, возможно, вызывать глобальное потепление. А ее отсутствие может порождать много багов. И вот один из интересных кейсов, на который все не обращают внимание и, при этом, все пользуются этой функциональностью.
Я говорю о попе элементов. Не вот этой ( | ), а вот этом
void pop_back();
void pop_front();
Эти методы достают из контейнера элементы из зада или из переда соответственно.
"Какие тут проблемы?" - спросите вы.
И я вам отвечу.
Что произойдет, если я вызову эти методы на пустом контейнере? Если вы задумались, то это нормально, обычно такого не происходит. Но вот я такой Маша-растеряша и забыл проверить на пустоту перед вызовом.
Будет UB.
Даже не исключение, которое можно обработать. Просто УБ. И можно УБиться в поисках бага, которая появится в следствии пропуска одной проверки.
Понятно, что так или иначе придется городить огород вокруг подобных моментов, когда что-то может пойти не так. Проблема конкретно этого кейса, что из сигнатура метода настолько безобидная, что даже и мысли не возникает, что может что-то не так пойти. А внезапно может прилететь по башке лопатой.
Туда же идут и методы front() и back(). Они дают такое же UB, когда контейнер пуст.
Почему так сложилось? Вопрос сложный.
Но не в этом суть.
Суть в том, что не нужно делать похожий интерфейс у своих классов.
Давайте пользователю сразу понять, что в функции может что-то пойти не так и эту ситуацию надо обработать.
Споры о дизайне - горячо любимый всеми процесс. Каждый может решать этот вопрос по-разному.
Даже что-то подобное, на мой взгляд, куда более безопасный дизайн:
bool pop_back() {
if (data_.empty()) {
return false;
}
// remove element
return true;
}
А если его еще и
аттрибутом nodiscard пометить, будет вообще щикарно(привет фанатам южного парка).
Может это и не лучшее решение для стандартной библиотеки. Вполне представляю, что это все бред и комитет лучше знает.
Но язык С++ никогда не славился своей безопасностью. И если вы можете своими силами обезопасить свой проект - нужно это делать. Даже таким несовершенным образом.
Stay safe. Stay cool.
#cppcore #STL