Почему допускается неопределенное поведение (а не компиляция / сбой)? - PullRequest
2 голосов
/ 10 мая 2010

Я понимаю причины расширения языка компилятора / интерпретатора, но почему поведение, у которого нет действительного определения, позволяет молча терпеть неудачу / делать странные вещи, а не выдавать ошибку компилятора? Это из-за дополнительной сложности (невозможной или просто трудоемкой) для компилятора, чтобы поймать их)?

P.S. какие языки имеют неопределенное поведение, а какие нет?

P.P.S. Существуют ли случаи неопределенного поведения, которое является невозможным / занимает слишком много времени, чтобы поймать компиляцию, и если да, то есть ли для этого веские причины / оправдания.

Ответы [ 3 ]

4 голосов
/ 10 мая 2010

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

int * p = new int(0);
// lots of conditional code, somewhere in which we do
int * q = p;
// lots more conditional code, somewhere in which we do
delete p;
// even more conditional code, somewhere in which we do
delete q;

Здесь указатель был удален дважды, что привело к неопределенному поведению. Обнаружить ошибку слишком сложно для такого языка, как C или C ++.

1 голос
/ 10 мая 2010

Во многом потому, что для достижения определенных целей это необходимо. Например, C и C ++ изначально использовались для написания операционных систем, включая такие вещи, как драйверы устройств. Для этого они использовали (среди прочего) прямой доступ к конкретным аппаратным расположениям, которые представляли устройства ввода-вывода. Предотвращение доступа к этим расположениям не позволило бы использовать C по прямому назначению (а C ++ был специально нацелен на предоставление всех тех же возможностей, что и C).

Другим фактором является действительно базовое решение между указанием языка и указанием платформы . Чтобы использовать одни и те же примеры, C и C ++ основаны на сознательном решении ограничить определение языком и оставить платформу, окружающую этот язык, отдельной. В нескольких альтернативах, с использованием Java и .NET в качестве пары наиболее очевидных примеров, вместо этого указываются целые платформы.

Оба они отражают основные различия в отношении к дизайну. Одной из основных заповедей дизайна C (в основном сохраненной в C ++) было «довериться программисту». Хотя об этом никогда не говорилось так прямо, базовая концепция «песочницы» Java была / основана на идее, что вы должны не доверять программисту.

Что касается того, какие языки имеют / не имеют неопределенного поведения, это маленький грязный секрет: для всех практических целей все из них имеют неопределенное поведение. Некоторые языки (опять же, C и C ++ являются яркими примерами) прилагают значительные усилия, чтобы указать, какое поведение не определено, в то время как многие другие либо пытаются утверждать, что его не существует (например, Java), либо по большей части игнорируют многие из «темных углов» "где это возникает (например, Паскаль, большинство .NET).

Те, кто утверждает, что его не существует, обычно создают самые большие проблемы. Java, например, включает в себя довольно много правил, которые пытаются , чтобы гарантировать согласованные результаты с плавающей запятой. В процессе они делают невозможным эффективное выполнение Java на небольшом количестве оборудования, но результаты с плавающей запятой все еще не гарантируют согласованности. Хуже того, модель с плавающей запятой, которую они запрашивают, не совсем идеальна, поэтому при некоторых обстоятельствах она препятствует получению наилучших результатов, которые вы могли бы (или, по крайней мере, заставляет вас проделать большую дополнительную работу, чтобы обойти то, что она требует) .

К чести Sun / Oracle (наконец) начал замечать проблему и сейчас работает над значительно другой моделью с плавающей запятой, которая должна стать улучшением. Я не уверен, было ли это включено в Java, но я подозреваю, что когда / если это произойдет, между кодом для старой модели и кодом для новой модели будет существенный «разрыв».

0 голосов
/ 10 мая 2010

Потому что разные операционные системы работают по-разному (...), и вы не можете просто сказать «сбой в этом случае», потому что это может быть что-то, что операционная система может сделать лучше.

...