Планируется ли добавление ожиданий в std::Optional?

Эта тема является спорной, но я нахожусь в лагере, который считает, что предварительные условия и инварианты классов должны быть защищены утверждениями, которые завершают программу, если нарушается контракт соответствующего компонента ПО - до тех пор, пока стоимость выполнения проверки утверждений составляет не является узким местом производительности.

Мне очень нравятся необязательные типы, и я часто их использую, но для меня стандартные библиотечные реализации std::Optional на данный момент непригодны для использования, так как сначала разыменование необязательного не выполняет проверки, содержит ли оно значение, и, во-вторых, ни одна из основных реализаций С++ не поддерживает/не реализует утверждения в стандартных библиотечных функциях, как сейчас.

Из использования std::Optional, которое я видел за эти годы, я не могу вспомнить ни одного случая, когда std::Optional использовался бы таким образом и в таком количестве, что проверки предварительных условий были бы узким местом производительности и непомерно высокими. Например, я никогда не видел, чтобы кто-то реализовал изображение маски в виде массива std:Optional.

Мой вопрос: есть ли уже какое-либо предложение (например, для С++ 22), которое добавляет функции контракта со стандартной библиотекой, в частности std::Optional?


Да, я знаю о методе value, который "защищен "в порядке исключения. Во-первых, я не большой поклонник неисключительного потока управления с использованием исключений (вы когда-нибудь пытались отлаживать такой код). Во-вторых, я считаю, что о силе и безопасности типа следует судить по его самому слабому звену.


Я пока не могу комментировать, поэтому я комментирую ответ Nicol Bolas здесь:

Спасибо за ответ, но, честно говоря, я не думаю, что он отвечает на мой вопрос. Просто для ясности. Я не прошу внести предложение, которое предписывает, чтобы std::abort вызывался при нарушении контракта (или "ожидаемом" закрытии). Вместо этого я спрашиваю, есть ли какие-либо планы по добавлению аннотаций к контрактам в стандартную библиотеку после предложения P0788. Я согласен с тем, что стандарт не должен предписывать, как конкретные реализации должны реагировать на такие нарушения контракта.


person B0rk4    schedule 14.07.2019    source источник
comment
Есть ли уже какое-либо предложение (например, для c++22), которое добавляет поддержку проектирования по контракту в стандартную библиотеку, в частности std::Optional? Это немного отличается от всех остальных ваших вопрос, потому что Contracts не делает то, что вы хотели. В частности, он ничего не гарантирует прекращения действия программы в случае нарушения контракта. Да, вы можете скомпилировать ваш код таким образом, чтобы контракты проверялись и программа закрывалась в случае сбоя, но нет гарантии, что это сделают другие люди.   -  person Nicol Bolas    schedule 14.07.2019
comment
@NicolBolas Это нормально. Я только хочу поддержать тех людей, которые решили расторгнуть контракт, когда он нарушается. Однако в настоящее время это невозможно. Конечно, другие решают никогда не прерываться на утверждениях и обнаруживают UB разными способами (например, с помощью дезинфицирующих адресов и т. д.), зачем мне вмешиваться?   -  person B0rk4    schedule 14.07.2019
comment
Дох. @NicolBolas хороший улов. Это была опечатка. утверждать -> исключение.   -  person B0rk4    schedule 14.07.2019
comment
У меня нет удобной ссылки, но я слышал, что Plauger из Dinkumware создал безопасную (дополнительную, для кода без релиза) версию стандартной библиотеки, чтобы помочь выявить ошибки. Но это не совсем то же самое, если вы хотите, чтобы это было в бинарном файле вашего выпуска.   -  person Eljay    schedule 14.07.2019
comment
@Элджей, да, явно есть пробел. Многие компании и проекты с открытым исходным кодом используют std::abort-подобные утверждения в своем производственном коде (или, по крайней мере, в оптимизированном предварительном коде а-ля RelWithDebInfo). Только основные реализации стандартных библиотек не поддерживают такую ​​функцию, что очень жаль.   -  person B0rk4    schedule 14.07.2019
comment
Насколько это «исключительно» для конкретного дополнительного доступа, определяет пользователь, поэтому существует версия, которая выдает ошибки. Если кто-то считает его «исключительным», он может использовать API, который решает, что он исключительный. @NicolBolas Следуя этому ходу мыслей, я бы сказал, что вам понадобятся два типа (std::Optional и std::exceptional) вместо определения типа компромисса «все-в-одном».   -  person B0rk4    schedule 14.07.2019
comment
@B0rk4: Следуя этой мысли, я бы сказал, что нужно два типа (std::Optional и std::exceptional), вместо того, чтобы определять компрометирующий тип «все-в-одном». Хм. , Зачем? Типы будут идентичны во всех отношениях, за исключением того, как работает operator*. Это привело бы к бессмысленному увеличению количества типов, в результате чего люди навязывали бы один способ поведения другим, выбирая тип, который использует механизм, который они предпочли бы использовать, и не давали бы получателю типа никакого права прибегать к использовать их предпочтительный инструмент (если есть). C++ не является безопасным языком.   -  person Nicol Bolas    schedule 14.07.2019
comment
@ B0rk4: Честно говоря, я не думаю, что это ответ на мой вопрос Но это ответ на ваш вопрос. Я даже процитировал ваш вопрос, когда отвечал на него. Вы спросили, будет ли функция контрактов (которую вы приравняли к дизайну по контракту, уравнение, с которым я бы не согласился, но вы, кажется, так его видите) будет применяться к стандартной библиотеке. И ответ был не только в том, что это не рассматривалось, но и в том, что оно было рассмотрено и отклонено как часть стандарта. То есть принятие P0788 явно исключает его. Большего не бывает.   -  person Nicol Bolas    schedule 14.07.2019
comment
@NicolBolas, спасибо за обсуждение. Это довольно проницательно. Позвольте мне сначала повторить свой вопрос и переименовать термины так, чтобы они были ближе к терминам в стандарте. Я не женат на дизайне по контракту и т. д.   -  person B0rk4    schedule 14.07.2019
comment
@ B0rk4: ... ваши правки только делают мой ответ более правильным. Прочтите цитату из P0788: давайте избегать любой спецификации, которая требует какой-либо конкретной технологии, реализация которой должна соответствовать спецификациям библиотеки. Добавлен акцент. expects (переименованный в pre) будет любой конкретной технологией, так что нет. Если вы спрашиваете, решил ли комитет по стандартам отменить решение, которое они только что приняли по этому поводу? Возможно нет.   -  person Nicol Bolas    schedule 15.07.2019


Ответы (2)


В ближайшем будущем это вопрос спорный, так как контракты были удалены из C++20 для некоторой доработки. Тем не менее, я думаю, что оставшийся текст все еще актуален:

Есть ли уже какое-либо предложение (например, для С++ 22), которое добавляет поддержку дизайна по контракту в стандартную библиотеку, в частности std:: optional?

Как раз наоборот: предложение P0788 было принято и сложенный в рабочий документ C++20, в котором говорится, что предварительные/постусловия не обязательны. для реализации с помощью функции контракта. Конкретная цель P0788 состояла в том, чтобы предотвратить формализованные требования к реализациям для использования контрактов для этих вещей (или концепций для подобных условий):

Давайте избегать любых спецификаций, требующих какой-либо конкретной технологии, реализация которой должна соответствовать спецификациям библиотеки.

Реализациям разрешено выражать такие условия в виде контрактов, но это не обязательно. Принимая P0788, комитет фактически рассматривает такие вещи как вопрос качества реализации, а не формальной спецификации.

C++ не является безопасным языком, и контракты не предназначены для того, чтобы сделать его безопасным. Нарушение контрактов является ошибкой программирования и приводит к UB, и именно так стандарт видит вещи. И предназначено, вы не можете навязать свое стремление к безопасности тем, кто этого не хочет.

person Nicol Bolas    schedule 14.07.2019

Ответ на мой собственный вопрос. Спасибо за обсуждение, которое указало в правильном направлении.

В настоящее время оператор разыменования std::Optional снабжен аннотацией "Requires" .

В духе P0788, Я ожидаю, что в ближайшем будущем пункт Requires будет изменен на Expects:

Давайте поставим перед собой цель со временем исключить все Requires: элементы из спецификаций нашей библиотеки, отдав предпочтение нашим новым элементам.

Кроме того, реализация стандартной библиотеки разрешена для любой технологии, соответствующей спецификациям "Ожидается".

  1. Давайте разрешим реализации использовать атрибуты Contracts [P0542R1] и/или любые другие технологии для соответствия спецификациям Expects: и Supplies:.

Все идет нормально. Только следующее утверждение делает его немного более сложным:

  1. Давайте считать, что пользовательский код, основанный на какой-либо конкретной технологии со стороны реализации, имеет неправильный формат и не требует диагностики.

Моя интерпретация вышеизложенного заключается в том, что пользователи не могут полагаться на то, что стандартные реализации будут защищать Expects каким-либо особым образом или вообще, но они могут.

На вопрос:

Есть ли уже какое-либо предложение (например, для С++ 22), которое добавляет функции контракта в стандартную библиотеку, в частности std:: optional?

Да, аннотации к контракту уже являются частью стандарта.

Как поступать с «ожидаемыми» предложениями, зависит от конкретной реализации библиотеки.

person B0rk4    schedule 14.07.2019
comment
Да, аннотации контрактов уже являются частью стандарта. Но... это ничего не добавляет к стандарту. Заявление о том, что это может случиться, ничего не добавляет, потому что реализации могли делать это в любом случае. Неопределенное поведение не определено. Представьте, что кто-то спрашивает, есть ли предложение для C++17, которое добавляет целые числа в дополнении до 2, и кто-то говорит, что да, реализации могут делать целые числа со знаком дополнением до 2. Но если реализации не требуются для обеспечения дополнения 2, тот факт, что они могут использоваться, совершенно бессмысленен. Вот почему С++ 20 предоставляет гарантию. - person Nicol Bolas; 15.07.2019