Шведский студент Йеспер Эквист (Jesper Öqvist) получил в универе домашнее задание: написать самую маленькую программу C, которая вылетает с ошибкой (segfault, SIGFPE). Обычно студенты в таких ситуациях используют деление на ноль.
Из этого кода ещё можно удалить пару байтов, если вместо инструкции использовать присвоение значения переменной.
В коде не указан тип данных для переменной
Осталось всего 16 знаков, если не считать избыточных пробелов, и больше оптимизировать уже некуда. Но на самом деле можно написать ещё более короткую сбойную программу. Дело в том, что в процессе компиляции программы компилятор создаёт один или больше объектных модулей с символьными ссылками на библиотеки и статические переменные и функции.
Символьная ссылка содержит только название переменной. Впоследствии объектный модуль обрабатывается компоновщиком, который заменяет символьные ссылки на адреса, чтобы сделать готовый исполнимый модуль.
Компилятор устанавливает точку входа — адрес в оперативной памяти, с которого начинается выполняться программа — и привязывает к нему
Интересно, что компоновщик не имеет понятия о типах данных разных объектов. Так что если мы заменим
Йеспер Эквист предлагает такую программу на C:
Такая программа вылетает с ошибкой, потому что пытается выполнить
Дальнейшие оптимизации очевидны. Можно использовать вышеупомянутый трюк с сокращением
Да и вообще, статические переменные в C по умолчанию инициализируются в ноль, так что можно сделать код ещё лаконичнее.
Вот она, самая маленькая сбойная программа на C.
int main()
{
return 1/0;
}
Из этого кода ещё можно удалить пару байтов, если вместо инструкции использовать присвоение значения переменной.
int main()
{
i=1/0;
}
В коде не указан тип данных для переменной
i
. Спецификации C89 предполагают, что в таком случае подразумевается целое int
. В C99 и некоторых других вариантах C это была бы ошибка. Предположим, что мы пишем на C89, в этом случае мы можем даже сократить int main()
до main()
.i;
main()
{
i=1/0;
}
Осталось всего 16 знаков, если не считать избыточных пробелов, и больше оптимизировать уже некуда. Но на самом деле можно написать ещё более короткую сбойную программу. Дело в том, что в процессе компиляции программы компилятор создаёт один или больше объектных модулей с символьными ссылками на библиотеки и статические переменные и функции.
Символьная ссылка содержит только название переменной. Впоследствии объектный модуль обрабатывается компоновщиком, который заменяет символьные ссылки на адреса, чтобы сделать готовый исполнимый модуль.
Компилятор устанавливает точку входа — адрес в оперативной памяти, с которого начинается выполняться программа — и привязывает к нему
main
в одном из объектных модулей. Вызов main
означает, что мы пытаемся выполнить инструкции по адресу, на который ссылается main
.Интересно, что компоновщик не имеет понятия о типах данных разных объектов. Так что если мы заменим
main
на статическую переменную, то компилятор с удовольствием создаст объектный модуль, а компоновщик потом заменит символьную ссылку на адрес в памяти.Йеспер Эквист предлагает такую программу на C:
int main=0;
Такая программа вылетает с ошибкой, потому что пытается выполнить
main
как функцию, в то время как компилятор поместил её в неисполняемый сегмент с данными.Дальнейшие оптимизации очевидны. Можно использовать вышеупомянутый трюк с сокращением
int
.main=0;
Да и вообще, статические переменные в C по умолчанию инициализируются в ноль, так что можно сделать код ещё лаконичнее.
main;
Вот она, самая маленькая сбойная программа на C.