Почему рекомендуется не разрешать запрашивать уровень контракта для контрактов С++ 20?

Текущий черновик C++ содержит в [ dcl.attr.contract.check ] p3:

Не должно быть никакого программного способа установки, изменения или запроса уровня сборки модуля перевода.

Я не понимаю, почему рекомендуется не разрешать запрашивать уровень контракта. С текущим макросом assert возможно определить, используется ли assert через макрос NDEBUG.

Запрос уровня контракта полезен в некоторых случаях, таких как:

  • добавление дополнительных переменных для отслеживания дополнительного состояния.
  • преобразование атомарного хранилища в атомарный сравнительный обмен для считывания значения.

Каково обоснование того, чтобы рекомендовать запрос уровня сборки невозможно?

Ответ 1

Рекомендуется, чтобы реализации не предоставляли такой запрос, потому что он нарушил бы использование смешанного уровня проверки.

В нынешнем виде нет ничего формального в том, чтобы строить библиотеку под одним уровнем проверки и связывать ее с кодом, созданным под другим. Однако, если код может легко запросить, какой уровень проверки доступен, это потенциально может нарушить этот вариант использования. Такой запрос может использоваться для воздействия на ABI типов и так далее. Если библиотека имеет такой интерфейс, то вы должны построить код потребления с тем же уровнем проверки, чтобы любые заголовки и тому подобное определяли один и тот же ABI.

Можно ли использовать такой запрос таким образом, чтобы он не влиял на ABI и интерфейсы? Конечно. Но обеспечение теста делает слишком легким запутывание.

В текущем состоянии библиотека может иметь собственный тест, #define который, как ожидается, будет определен при компиляции с определенным уровнем проверки или каким-то другим образом. Но такое определение сейчас является частью интерфейса вашей библиотеки. Это только часть вашей документации по сборке; если люди собирают вашу библиотеку с уровнем проверки X, они должны предоставить #define. И любой код, потребляющий библиотеку, созданную в таких условиях, также должен предоставить это определение.

И это лучшая часть: потребляющий код не должен разделять ваш уровень проверки. Они должны поделиться вашим определением, но не фактическим уровнем проверки. Ваше определение принадлежит библиотеке; уровень проверки принадлежит пользователю.

Ответ 2

Это описано в дизайнерской работе, P0380:

Установка обработчика нарушения может быть очень деликатной проблемой, поэтому некоторые реализации наложат серьезные ограничения на обработчики, которые могут быть установлены и как. Например, обработчик нарушения может использоваться для внедрения троянского коня в систему, поэтому системы, чувствительные к безопасности, предотвратят это (например, разрешив установку только утвержденных обработчиков нарушения).

а также:

Нет (намеренно) способа установить эти параметры в исходном коде. В противном случае возникнут сложности и возможности для ошибок и нарушений безопасности.

Конечно, ничто не мешает вам предоставлять макросы по вашему выбору в дополнение к уровню сборки при компиляции.