В C# это был вопрос производительности. А именно, сравнительное тестирование из поля.
, Когда C# был новым, Microsoft надеялась, что много разработчиков C++ переключится на него. Они знали, что многие люди C++ думали о C++, как являющемся быстрым, особенно быстрее, чем языки, которые "потратили впустую" время на автоматическое управление памятью и т.п..
И потенциальные приемные родители и рецензенты журнала, вероятно, получат копию нового C#, установят его, создадут тривиальное приложение, которое никто никогда не писал бы в реальном мире, выполнял бы его в жестком цикле и имел бы размеры, сколько времени он взял. Тогда они приняли бы решение для своей компании или опубликовали бы статью на основе того результата.
то, что их тест показал C#, чтобы быть медленнее, чем исходно скомпилированный C++, является видом вещи, которая оказалась бы людьми от C# быстро. То, что Ваше приложение C# собирается поймать переполнение/потерю значимости автоматически, является видом вещи, которую они могли бы пропустить. Так, это прочь по умолчанию.
я думаю, что очевидно, что 99% времени мы хотим/, проверенный для хождения. Это - неудачный компромисс.
Я думаю, что производительность является довольно серьезным основанием. Если Вы рассматриваете каждую инструкцию в типичной программе, которая увеличивает целое число, и если бы вместо простого op для добавления 1 она должна была проверить каждый раз, то если добавление 1 переполнило бы типа, то стоимость в дополнительных циклах будет довольно серьезна.
Вы работаете под предположением, что целочисленное переполнение всегда является нежелательным поведением.
Иногда целочисленное переполнение является желаемым поведением. Одним примером, который я видел, является представление абсолютного значения заголовка как число фиксированной точки. Учитывая неподписанный интервал, 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;
}
существуют, вероятно, другие ситуации, где переполнение приемлемо, подобно этому примеру.
C/C++ никогда не передает под мандат поведение прерывания. Даже очевидное подразделение 0 является неопределенным поведением в C++, не указанным видом прерывания.
язык C не имеет никакого понятия захвата, если Вы не считаете сигналы.
C++ имеет принцип разработки, что он не представляет наверху не существующий в C, если Вы не просите его. Таким образом, Stroustrup не хотел бы передавать под мандат это, целые числа ведут себя способом, который требует любой явной проверки.
Некоторые ранние компиляторы и легкие реализации для ограниченных аппаратных средств, не поддерживают исключения вообще, и исключения могут часто отключаться с параметрами компилятора. Передавание под мандат исключений для созданного-ins языка было бы проблематично.
, Даже если бы C++ сделал целые числа проверенными, 99% программистов в первые годы повернулись бы, если прочь для производительности повышают...
Поскольку проверка переполнение занимает время. Каждая примитивная математическая операция, которая обычно переводит в единственную инструкцию по сборке, должна была бы включать проверку на переполнение, приводящее к нескольким инструкциям по сборке, потенциально приводящим к программе, которая несколько раз медленнее.
Это - вероятная 99%-я производительность. На x86 должен был бы проверить флаг переполнения на каждой операции, которая будет огромным хитом производительности.
другой 1% покрыл бы те случаи, где люди делают необычные побитовые обработки или 'неточный' в смешивании и неподписанных операций со знаком и хотят семантику переполнения.
Назад совместимость является большой. С C предполагалось, что Вы обращали достаточно внимания на размер Ваших типов данных это, если по/недостаточно заполнять произошедшему, это, именно это Вы хотели. Тогда с C++, C# и Java, очень мало измененным с тем, как "встроенные" типы данных работали.
Мое понимание того, почему ошибки не были бы повышены по умолчанию во времени выполнения, сводится к наследию желания создать языки программирования с подобным КИСЛОТЕ поведением. А именно, принцип, что что-либо, что Вы кодируете его, чтобы сделать (или не кодируют), это сделает (или не сделает). Если Вы не кодировали некоторый обработчик ошибок, то машина не "примет" на основании никакого обработчика ошибок, что Вы действительно хотите сделать смешную, склонную к катастрофическому отказу вещь, которую Вы говорите ему делать.
(ссылка ACID: http://en.wikipedia.org/wiki/ACID )