Почему целочисленное деление на ноль приводит к исключению с плавающей запятой?

Деление на ноль в программе на C приводит к аномальному завершению с сообщением об ошибке Floating point exception (core dumped). Это неудивительно для деления с плавающей запятой, но почему оно говорит об этом, когда происходит целочисленное деление на ноль? Действительно ли целочисленное деление действительно использует FPU под капотом?

(Кстати, все это на Linux под x86).

Ответ 1

Действительно ли целочисленное деление действительно использует FPU под капотом?

Нет, Linux просто генерирует SIGFPE в этом случае (это устаревшее имя, использование которого теперь расширено). Действительно, спецификация Single Unix определяет SIGFPE как "Ошибочная арифметическая операция".

Ответ 2

man signal упоминает:

Целочисленное деление на ноль имеет результат undefined. На некоторых архитектурах он будет генерировать сигнал SIGFPE. (Также разделение наибольшего отрицательного целого на -1 может генерировать SIGFPE.)

Ответ 3

Мое предположение об историческом объяснении этого было бы в том, что исходное оборудование unix не создало ловушку для целочисленного деления на ноль, поэтому имя SIGFPE имело смысл. (Программисты сборки PDP, подтвердите?). Затем, когда система была портирована (или в случае Linux, переопределена) на аппаратное обеспечение с целочисленной ловушкой деления на нуль, не считалось целесообразным добавлять новый номер сигнала, поэтому старый приобрел новое значение и теперь имеет слегка запутанное имя.

Ответ 4

Для этого может быть много разных причин.

Например, блок FPU на платформе x86 поддерживает как плавающие, так и целочисленные форматы для чтения аргументов и записи результатов. Назад, когда сама платформа была 16-бит, некоторые компиляторы использовали FPU для выполнения деления с 32-разрядными целочисленными операндами (поскольку нет потери точности для 32-битных данных). В таких обстоятельствах не было бы ничего необычного в получении подлинной ошибки FPU для недопустимого 32-разрядного целочисленного деления.