Почему языки не повышают ошибки на целочисленном переполнении по умолчанию?

43
задан phuclv 29 August 2015 в 02:27
поделиться

8 ответов

В C# это был вопрос производительности. А именно, сравнительное тестирование из поля.

, Когда C# был новым, Microsoft надеялась, что много разработчиков C++ переключится на него. Они знали, что многие люди C++ думали о C++, как являющемся быстрым, особенно быстрее, чем языки, которые "потратили впустую" время на автоматическое управление памятью и т.п..

И потенциальные приемные родители и рецензенты журнала, вероятно, получат копию нового C#, установят его, создадут тривиальное приложение, которое никто никогда не писал бы в реальном мире, выполнял бы его в жестком цикле и имел бы размеры, сколько времени он взял. Тогда они приняли бы решение для своей компании или опубликовали бы статью на основе того результата.

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

я думаю, что очевидно, что 99% времени мы хотим/, проверенный для хождения. Это - неудачный компромисс.

38
ответ дан Jay Bazuzi 26 November 2019 в 22:43
поделиться

Я думаю, что производительность является довольно серьезным основанием. Если Вы рассматриваете каждую инструкцию в типичной программе, которая увеличивает целое число, и если бы вместо простого op для добавления 1 она должна была проверить каждый раз, то если добавление 1 переполнило бы типа, то стоимость в дополнительных циклах будет довольно серьезна.

26
ответ дан David Hill 26 November 2019 в 22:43
поделиться

Вы работаете под предположением, что целочисленное переполнение всегда является нежелательным поведением.

Иногда целочисленное переполнение является желаемым поведением. Одним примером, который я видел, является представление абсолютного значения заголовка как число фиксированной точки. Учитывая неподписанный интервал, 0 0 или 360 градусов, и макс. целое число без знака на 32 бита (0xffffffff) является самым большим значением чуть ниже 360 градусов.

int main()
{
    uint32_t shipsHeadingInDegrees= 0;

    // Rotate by a bunch of degrees
    shipsHeadingInDegrees += 0x80000000; // 180 degrees
    shipsHeadingInDegrees += 0x80000000; // another 180 degrees, overflows 
    shipsHeadingInDegrees += 0x80000000; // another 180 degrees

    // Ships heading now will be 180 degrees
    cout << "Ships Heading Is" << (double(shipsHeadingInDegrees) / double(0xffffffff)) * 360.0 << std::endl;

}

существуют, вероятно, другие ситуации, где переполнение приемлемо, подобно этому примеру.

15
ответ дан phuclv 26 November 2019 в 22:43
поделиться

C/C++ никогда не передает под мандат поведение прерывания. Даже очевидное подразделение 0 является неопределенным поведением в C++, не указанным видом прерывания.

язык C не имеет никакого понятия захвата, если Вы не считаете сигналы.

C++ имеет принцип разработки, что он не представляет наверху не существующий в C, если Вы не просите его. Таким образом, Stroustrup не хотел бы передавать под мандат это, целые числа ведут себя способом, который требует любой явной проверки.

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

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

8
ответ дан Steve Jessop 26 November 2019 в 22:43
поделиться

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

7
ответ дан Dima 26 November 2019 в 22:43
поделиться

Это - вероятная 99%-я производительность. На x86 должен был бы проверить флаг переполнения на каждой операции, которая будет огромным хитом производительности.

другой 1% покрыл бы те случаи, где люди делают необычные побитовые обработки или 'неточный' в смешивании и неподписанных операций со знаком и хотят семантику переполнения.

6
ответ дан Rob Walker 26 November 2019 в 22:43
поделиться

Назад совместимость является большой. С C предполагалось, что Вы обращали достаточно внимания на размер Ваших типов данных это, если по/недостаточно заполнять произошедшему, это, именно это Вы хотели. Тогда с C++, C# и Java, очень мало измененным с тем, как "встроенные" типы данных работали.

4
ответ дан Eclipse 26 November 2019 в 22:43
поделиться

Мое понимание того, почему ошибки не были бы повышены по умолчанию во времени выполнения, сводится к наследию желания создать языки программирования с подобным КИСЛОТЕ поведением. А именно, принцип, что что-либо, что Вы кодируете его, чтобы сделать (или не кодируют), это сделает (или не сделает). Если Вы не кодировали некоторый обработчик ошибок, то машина не "примет" на основании никакого обработчика ошибок, что Вы действительно хотите сделать смешную, склонную к катастрофическому отказу вещь, которую Вы говорите ему делать.

(ссылка ACID: http://en.wikipedia.org/wiki/ACID )

-4
ответ дан devinmoore 26 November 2019 в 22:43
поделиться
Другие вопросы по тегам:

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