Введение
В компьютерном программировании, утверждение – это концепция, заключающаяся в том, что предикат всегда истинен в определенной точке выполнения кода. В компьютерном программировании, особенно при использовании императивного подхода, утверждение представляет собой предикат (булевозначную функцию, зависящую от пространства состояний и обычно выраженную в виде логического утверждения с использованием переменных программы), привязанный к конкретной точке программы, который должен всегда возвращать истину в этой точке выполнения. Утверждения могут помочь программисту понять код, компилятору – скомпилировать его, а программе – выявить собственные ошибки. Для этого некоторые программы проверяют утверждения, вычисляя предикат непосредственно во время работы. Если предикат оказывается ложным – происходит сбой утверждения – программа считает себя неисправной и обычно намеренно завершается аварийно или генерирует исключение об ошибке утверждения.
the computer programming concept
In computer programming, specifically when using the imperative programming paradigm, an assertion is a predicate (a Boolean valued function over the state space, usually expressed as a logical proposition using the variables of a program) connected to a point in the program, that always should evaluate to true at that point in code execution. Assertions can help a programmer read the code, help a compiler compile it, or help the program detect its own defects. For the latter, some programs check assertions by actually evaluating the predicate as they run. Then, if it is not in fact true – an assertion failure – the program considers itself to be broken and typically deliberately crashes or throws an assertion failure exception.
Использование
В языках, таких как Eiffel, утверждения являются частью процесса разработки; в других языках, таких как C и Java, они используются только для проверки допущений во время выполнения. В обоих случаях их можно проверять на корректность во время выполнения, но обычно их также можно отключать.
Заявления о конструкции в договоре
Утверждения могут служить формой документации: они могут описывать состояние, в котором код должен находиться перед началом выполнения (его предусловия), и состояние, в котором код должен перейти после завершения выполнения (посткондиции); они также могут задавать инварианты класса. Eiffel интегрирует такие утверждения непосредственно в язык и автоматически извлекает их для документирования класса. Это важная часть методологии разработки по контракту. Этот подход полезен и в языках, которые не поддерживают его явно: преимущество использования операторов утверждений вместо утверждений в комментариях заключается в том, что программа может проверять утверждения при каждом запуске; если утверждение перестает быть истинным, сообщается об ошибке. Это предотвращает расхождение кода с утверждениями.
Утверждения в течение цикла разработки
В течение цикла разработки программист обычно запускает программу с включенными проверками (утверждениями). Когда проверка (утверждение) не проходит, программист немедленно уведомляется о проблеме. Многие реализации проверок (утверждений) также останавливают выполнение программы: это полезно, поскольку если программа продолжит работу после нарушения проверки (утверждения), она может повредить свое состояние и затруднить определение причины проблемы. Используя информацию, предоставляемую сообщением о неудачной проверке (утверждении) – например, местоположение ошибки и, возможно, трассировку стека, или даже полное состояние программы, если среда поддерживает дампы памяти или если программа выполняется в отладчике – программист обычно может исправить ошибку. Таким образом, проверки (утверждения) предоставляют очень мощный инструмент для отладки.
Утверждения в производственной среде
Когда программа развертывается в рабочей среде, проверки обычно отключаются, чтобы избежать каких-либо накладных расходов или побочных эффектов, которые они могут вызывать. В некоторых случаях проверки полностью отсутствуют в развернутом коде, например, проверки в C/C++, реализованные через макросы. В других случаях, таких как Java, проверки присутствуют в развернутом коде и могут быть включены непосредственно в рабочей среде для отладки. Проверки также могут использоваться для гарантии компилятору, что определенная пограничная ситуация недостижима, тем самым позволяя проводить определенные оптимизации, которые иначе были бы невозможны. В этом случае отключение проверок может фактически снизить производительность.
Недействительные утверждения
Большинство языков программирования позволяют включать или отключать проверки утверждений глобально, а иногда и независимо друг от друга. Проверки утверждений обычно включаются в процессе разработки и отключаются на финальном этапе тестирования и при выпуске продукта пользователям. Отключение проверки утверждений позволяет избежать затрат на их вычисление, при этом (если утверждения не имеют побочных эффектов) сохраняя тот же результат в нормальных условиях. В нештатных ситуациях отключение проверки утверждений может привести к продолжению работы программы, которая в противном случае была бы прервана. Иногда это может быть желательным поведением. Некоторые языки, такие как C, YASS и C++, позволяют полностью исключить проверки утверждений на этапе компиляции с помощью препроцессора. Аналогично, запуск интерпретатора Python с флагом "O" (обозначающим "оптимизация") приведет к тому, что генератор кода Python не будет генерировать байт-код для операторов `assert`. В Java для включения проверок утверждений требуется передать специальную опцию в среду выполнения. Если эта опция не указана, проверки утверждений игнорируются, но остаются в коде, если только не будут оптимизированы JIT-компилятором во время выполнения или явно исключены программистом путем заключения каждого утверждения в условный оператор `if (false)`. Программисты могут реализовывать собственные проверки в коде, которые всегда активны, обходя или изменяя стандартные механизмы проверки утверждений языка.
История
В докладах фон Неймана и Голдстайна 1947 года, посвященных разработке машины IAS, они описали алгоритмы, использующие раннюю версию блок-схем, в которых включали утверждения: "Вероятно, верно, что всякий раз, когда C фактически достигает определенной точки на блок-схеме, одна или несколько связанных переменных обязательно будут иметь определенные значения, обладать определенными свойствами или удовлетворять определенным взаимосвязям. Более того, в этой точке мы можем указать на обоснованность этих ограничений. Поэтому мы будем обозначать каждую область, в которой обоснованность таких ограничений утверждается, специальным блоком, который мы называем блоком утверждения". Алан Тьюринг поддерживал утвердительный метод доказательства корректности программ. В докладе "Проверка большой программы" в Кембридже 24 июня 1949 года Тьюринг предложил: "Как можно проверить большую программу, чтобы убедиться в ее правильности? Чтобы задача проверки не была слишком сложной, программист должен сделать ряд четких утверждений, которые можно проверить по отдельности, и из которых легко вытекает корректность всей программы".