Семантические ошибки

Семантические ошибки могут быть обнаружены компилятором или нет? Если не, когда ошибки становятся обнаруженными?

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

Например:

n3=n1*n2;//n1 is integer, n2 is a string, n3 is an integer

Вышеупомянутый оператор является семантически неправильным.

Но при чтении C Краткой информации Плюс Stephen Prata я нашел следующее утверждение

Компилятор не обнаруживает семантические ошибки, потому что они не нарушают правила C. Компилятор не имеет никакого способа предугадать Ваши истинные намерения. Это предоставляет Вам право находить эти виды ошибок. Один путь состоит в том, чтобы сравнить то, что делает программа, к какому Вы ожидали, что это сделает.

Если не компилятор, кто обнаруживает те ошибки?

Я пропускаю что-то?

6
задан Gautam Kumar 12 May 2010 в 05:30
поделиться

11 ответов

Слово «семантический» неоднозначно, и вы столкнулись с двумя немного разными значениями в этих разных контекстах.

Первое значение (ваш код) связано с тем, как компилятор интерпретирует код, который вы вводите. Но есть разные степени интерпретации для этого - синтаксис - это один уровень, где интерпретация просто решает, что n1 * n2 означает, что вы хотите выполнить умножение. Но здесь есть и более высокий уровень интерпретации - если n1 - целое число, а n2 - с плавающей запятой, каков результат? Что, если я его закруглю, должен ли он быть округлен, усечен и т. Д.? Это «семантические» вопросы, а не синтаксические, но кто-то где-то решил, что да, компилятор может ответить на них для большинства людей.

Они также решили, что у компилятора есть пределы того, что он может (и должен!) Интерпретировать.Например, он может решить, что приведение к int является усечением, а не округлением, но он не может решить, что вы действительно хотите, когда вы пытаетесь умножить массив на число.

(Иногда люди решают, что они МОГУТ. В Python, [1] * 3 == [1,1,1] .)

Второе значение относится к гораздо более широкой области. Если результат этой операции предполагается отправить на периферийное устройство, которое может принимать значения от 0x000 до 0xFFF, и вы умножаете 0x7FF на 0x010, очевидно, вы допустили семантическую ошибку. Разработчики периферийных устройств должны решить, нужно ли и как с этим справиться. Вы, как программист, также можете решить провести некоторые проверки работоспособности. Но компилятор не имеет представления об этих внешних семантических ограничениях или о том, как их применять (фильтровать вводимые пользователем данные? Возвращать ошибку? Усекать? Перенос?), О чем говорит вторая цитата.

5
ответ дан 8 December 2019 в 17:19
поделиться

"Семантическая ошибка" - это другой термин для "логической ошибки", когда вы буквально пишете неправильный код. Например, написать n3=n1*n2, когда на самом деле вы хотели разделить - у компилятора нет способа сказать, что ваш алгоритм должен был разделить вместо умножения; вы сказали ему умножить, вот он и умножает.

Ошибка, которую вы описали в своем примере, является ошибкой безопасности типов, и компиляторы могут отловить ее на этапе проверки типов (если язык сильно типизирован)

.
5
ответ дан 8 December 2019 в 17:19
поделиться

Семантические ошибки — это все те, когда ваш код делает то, что вы не намеревались.

Эти ошибки могут быть пойманы путем тестирования или анализа.

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

Тестирование — это когда вы даете своей программе некоторые входные данные, которые, как ожидается, произведут заданный вывод, если программа семантически верна. Поэтому, если фактический вывод не соответствует ожидаемому, программа семантически неверна.

Проще говоря, именно ВЫ разработчик или тестировщик должны улавливать семантические ошибки.

1
ответ дан 8 December 2019 в 17:19
поделиться

Эта цитата говорит о таких вещах, как выполнение x <= 1, где вы действительно должны были сделать x < 1.

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

0
ответ дан 8 December 2019 в 17:19
поделиться

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

Семантическая ошибка - это ошибка, которая возникает, когда ваша программа компилирует, но не делает то, что вы хотите.

0
ответ дан 8 December 2019 в 17:19
поделиться

Существует три основных типа ошибок.

1) Синтаксические ошибки. Это недопустимый код, который компилятор не понимает, например ваш пример умножения строки на целое число в C. Компилятор обнаружит их, потому что он не может их скомпилировать.

2) Семантические ошибки. Это правильный код, который понимает компилятор, но он не соответствует тому, что задумал программист. Они могут использовать неправильную переменную, неправильную операцию или операции в неправильном порядке. Компилятор не может их обнаружить.

Существует третий класс, который может быть самым дорогим:

3) Ошибки проектирования. Код правильный, без ошибок и делает именно то, что вы задумали. Но ваши намерения ошибочны, например основаны на неправильных предположениях, неправильных моделях или вы использовали неправильные формулы, неправильно поняли клиента и т. д.

3
ответ дан 8 December 2019 в 17:19
поделиться

Строковые литералы и строки представлены в памяти в виде чисел (байтов / м слов или высокоуровневыми - краткими, целыми числами). C - это низкоуровневый уровень программирования, на котором все приближено к машинному / ассемблерному уровню. Таким образом, умножение числа на строковый литерал (если это массив, это будет неверно) правильно, потому что этот строковый литерал будет фактически (после компиляции) числом.

0
ответ дан 8 December 2019 в 17:19
поделиться

Я думаю, что писатель, написавший книгу, определил «семантику» иначе. Для большинства компиляторов есть этап, включающий некоторые семантические проверки .

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

1
ответ дан 8 December 2019 в 17:19
поделиться

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

Семантическая ошибка больше похожа на что-то, что хорошо компилируется (вплоть до самых типов), но не то, что вы хотите. Семантические ошибки являются частью вашего алгоритма в большей степени, чем ваш фактический синтаксис.

0
ответ дан 8 December 2019 в 17:19
поделиться

Кто обнаруживает эти ошибки, если не компилятор?

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

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

Вы можете дополнить компилятор статическим анализатором для обнаружения некоторых или всех ошибок в программе, но они также могут иметь ложных срабатываний : они могут выдавать предупреждение для фрагмента кода, который работает без ошибок.

0
ответ дан 8 December 2019 в 17:19
поделиться

На самом деле (поскольку в C нет типа string , а есть только char * ), вы можете очень хорошо умножить n1 на n2 . Операция легальна и четко определена, поэтому компилятор не выдаст ошибку.

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

-1
ответ дан 8 December 2019 в 17:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: