Какой самый короткий код вызывает переполнение стека?
В ознаменование публичного запуска Stack Overflow, какой самый короткий код вызывает переполнение стека? Любые приветствия.
ETA: просто чтобы понять этот вопрос, поскольку я являюсь случайным пользователем Схемы: "рекурсия" хвоста - это действительно итерация, и любое решение, которое может быть превращено в итеративное решение относительно тривиально приличным компилятором не будет учитываться.:-P
ETA2: теперь я выбрал "лучший ответ"; см. этот пост для обоснования. Спасибо всем, кто внес свой вклад!: -)
Ответы
Ответ 1
Все эти ответы и отсутствие Befunge? Я бы поставил справедливое количество его кратчайшего решения из всех:
1
Не шучу. Попробуйте сами: http://www.quirkster.com/iano/js/befunge.html
EDIT: Думаю, мне нужно объяснить это. 1 операнд подталкивает 1 к внутреннему стеку Befunge, а отсутствие чего-либо еще помещает его в цикл по правилам языка.
Используя предоставленный интерпретатор, вы в конечном итоге - и я подразумеваем в конце концов - попадаем в точку, где массив Javascript, представляющий стек Befunge, становится слишком большим для перераспределения браузера. Если у вас был простой интерпретатор Befunge с меньшим и ограниченным стеком - как в случае с большинством языков ниже - эта программа приведет к более заметному переполнению быстрее.
Ответ 2
Прочитайте эту строку и сделайте то, что она говорит дважды.
Ответ 3
Вы также можете попробовать это на С#.net
throw new StackOverflowException();
Ответ 4
Nemerle
Этот выдает компилятор с помощью StackOverflowException:
def o(){[o()]}
Ответ 5
Мое самое лучшее (в сборке x86):
push eax
jmp short $-1
что приводит к 3 байтам объектного кода (50 EB FD
). Для 16-битного кода это также возможно:
call $
что также приводит к 3 байтам (E8 FD FF
).
Ответ 6
PIC18
Ответ PIC18, заданный TK, приводит к следующим инструкциям (двоичным):
overflow
PUSH
0000 0000 0000 0101
CALL overflow
1110 1100 0000 0000
0000 0000 0000 0000
Однако CALL самостоятельно выполняет переполнение стека:
CALL $
1110 1100 0000 0000
0000 0000 0000 0000
Меньше, быстрее PIC18
Но RCALL (относительный вызов) по-прежнему меньше (не глобальная память, поэтому нет необходимости в дополнительных 2 байтах):
RCALL $
1101 1000 0000 0000
Итак, самый маленький на PIC18 - это одна команда, 16 бит (два байта). Это займет 2 цикла инструкций для каждого цикла. В течение 4 тактов за цикл инструкций у вас есть 8 тактов. PIC18 имеет 31 уровень стека, поэтому после 32-го цикла он переполнит стек в 256 тактов. На 64 МГц вы бы переполнили стек в 4 микросекунды и 2 байта.
PIC16F5x (еще меньше и быстрее)
Однако в серии PIC16F5x используются 12-битные команды:
CALL $
1001 0000 0000
Опять же, два цикла инструкций для каждого цикла, 4 такта на инструкцию, так что 8 тактов за цикл.
Однако PIC16F5x имеет двухуровневый стек, поэтому в третьем цикле он будет переполняться в 24 инструкциях. На 20 МГц он будет переполняться в 1,2 микросекундах и 1,5 байта.
Intel 4004
Intel 4004 содержит инструкцию подпрограммы 8 бит:
CALL $
0101 0000
Для любопытного, что соответствует ascii 'P'. С трехуровневым стекем, который занимает 24 тактовых цикла в общей сложности 32,4 микросекунды и один байт. (Если вы не разгоняете свой 4004 - продолжайте, вы знаете, что хотите.)
Который такой же маленький, как и ожидающий ответ, но намного, намного быстрее, чем код befunge, запущенный в текущих интерпретаторах.
Ответ 7
С#:
public int Foo { get { return Foo; } }
Ответ 8
Переполнение Hoot!
// v___v
let rec f o = f(o);(o)
// ['---']
// -"---"-
Ответ 9
Каждая задача нуждается в правильном инструменте. Знакомьтесь с SO Overflow, оптимизированным для создания:
so
Ответ 10
TeX:
\def~{~.}~
Результаты в:
! TeX capacity exceeded, sorry [input stack size=5000].
~->~
.
~->~
.
~->~
.
~->~
.
~->~
.
~->~
.
...
<*> \def~{~.}~
LaTeX:
\end\end
Результаты в:
! TeX capacity exceeded, sorry [input stack size=5000].
\end #1->\csname end#1
\endcsname \@checkend {#1}\expandafter \endgroup \[email protected]
<*> \end\end
Ответ 11
Ассемблер Z-80 - в ячейке памяти 0x0000:
rst 00
один байт - 0xC7 - бесконечный цикл нажатия текущего ПК в стек и переход к адресу 0x0000.
Ответ 12
По-английски:
recursion = n. See recursion.
Ответ 13
Другой пример PHP:
<?
require(__FILE__);
Ответ 14
Как насчет следующего в BASIC:
10 GOSUB 10
(У меня нет интерпретатора BASIC, я боюсь, так что думаю).
Ответ 15
Я любил Cody ответить кучи, так что вот мой аналогичный вклад, в С++:
template <int i>
class Overflow {
typedef typename Overflow<i + 1>::type type;
};
typedef Overflow<0>::type Kaboom;
Не для входа в гольф для кодов каким-либо образом, но все же, для переполнения мета-стека!:-P
Ответ 16
Здесь мой вклад C, весом в 18 символов:
void o(){o();o();}
Это намного сложнее оптимизировать хвост!:-P
Ответ 17
Использование пакетного файла Window с именем "s.bat":
call s
Ответ 18
Javascript
Чтобы обрезать еще несколько персонажей и вытащить себя из большего количества магазинов программного обеспечения, отпустите:
eval(i='eval(i)');
Ответ 19
Groovy:
main()
$groovy stack.groovy:
Caught: java.lang.StackOverflowError
at stack.main(stack.groovy)
at stack.run(stack.groovy:1)
...
Ответ 20
Скажите, пожалуйста, что означает аббревиатура GNU".
Ответ 21
Person JeffAtwood;
Person JoelSpolsky;
JeffAtwood.TalkTo(JoelSpolsky);
Здесь надеюсь на отсутствие рекурсии хвоста!
Ответ 22
C - это не кратчайший, но без рекурсии. Он также не переносится: он падает в Solaris, но некоторые реализации alloca() могут возвращать здесь ошибку (или вызвать malloc()). Требуется вызов printf().
#include <stdio.h>
#include <alloca.h>
#include <sys/resource.h>
int main(int argc, char *argv[]) {
struct rlimit rl = {0};
getrlimit(RLIMIT_STACK, &rl);
(void) alloca(rl.rlim_cur);
printf("Goodbye, world\n");
return 0;
}
Ответ 23
Python
so=lambda:so();so()
В качестве альтернативы:
def so():so()
so()
И если оптимизированные хвосты Python...:
o=lambda:map(o,o());o()
Ответ 24
perl в 12 символах:
$_=sub{&$_};&$_
bash в 10 символах (важно место в функции):
i(){ i;};i
Ответ 25
попробуйте поставить более 4 пирожков на одном гамбургере. переполнение стека.
Ответ 26
Я выбираю "лучший ответ" после этого сообщения. Но сначала я хотел бы отметить некоторые очень оригинальные вклады:
- aku. Каждый из них исследует новый и оригинальный способ возникновения. Идея делать f (x) ⇒ f (f (x)) является той, которую я расскажу в следующей статье ниже.: -)
- Cody, который дал компилятору Nemerle переполнение стека.
- И (немного неохотно), GateKiller один о том, чтобы выбросить исключение. -Р
Как мне нравится вышеизложенное, задача состоит в том, чтобы делать код в гольф, и, чтобы быть справедливым для респондентов, я должен присудить "лучший ответ" кратчайшему коду, который является записью Befunge; Я не верю, что кто-то сможет победить это (хотя Конрад, конечно же, попытался), так поздравляю Патрика!
Увидев большое количество решений, я удивлен, что никто (на момент написания письма) не поднял Y combinator (см. эссе Dick Gabriel, Почему Y, для праймера). У меня есть рекурсивное решение, которое использует подход Y combinator, а также aku f (f (x)).: -)
((Y (lambda (f) (lambda (x) (f (f x))))) #f)
Ответ 27
Вот еще один интересный из Схемы:
((lambda (x) (x x)) (lambda (x) (x x)))
Ответ 28
Java
Немного более короткая версия решения Java.
class X{public static void main(String[]a){main(a);}}
Ответ 29
xor esp, esp
ret
Ответ 30
3 байта:
label:
pusha
jmp label
Обновление
Согласно (старой?) документации Intel (?), это также 3 байта:
label:
call label