컴파일러 폭탄 만들기


372

소개

압축 폭탄 , XML 폭탄 등에 익숙 할 것입니다 . 간단히 말해서, 이들은 순진한 소프트웨어로 해석 할 때 막대한 출력을 생성하는 (상대적으로) 작은 파일입니다. 여기서의 과제는 동일한 방식으로 컴파일러를 남용하는 것입니다.

도전

512 바이트 이하를 차지하고 가장 가능한 공간을 차지하는 파일로 컴파일되는 소스 코드를 작성하십시오. 가장 큰 출력 파일이 이깁니다!

규칙

따라서 몇 가지 중요한 설명, 정의 및 제한이 있습니다.

  • 컴파일 결과는 ELF 파일, Windows Portable Executable (.exe) 또는 JVM 또는 .Net의 CLR에 대한 가상 바이트 코드 여야합니다 (요청하는 경우 다른 유형의 가상 바이트 코드도 가능함). 업데이트 : Python의 .pyc / .pyo 출력도 계산 됩니다.
  • 선택 언어를 이러한 형식 중 하나로 직접 컴파일 할 수없는 경우, 코드 변환 후 컴파일도 허용됩니다 ( 업데이트 : 동일한 언어를 두 번 이상 사용하지 않는 한 여러 번 변환 할 수 있음 ).
  • 소스 코드는 여러 파일과 리소스 파일로 구성 될 수 있지만 이러한 모든 파일의 합산 크기는 512 바이트를 초과하지 않아야합니다.
  • 소스 파일 및 선택 언어의 표준 라이브러리 이외의 다른 입력은 사용할 수 없습니다. 정적 링크 표준 라이브러리는 지원 될 때 정상입니다. 특히 타사 라이브러리 나 OS 라이브러리가 없습니다.
  • 명령 또는 일련의 명령을 사용하여 컴파일을 호출 할 수 있어야합니다. 컴파일 할 때 특정 플래그가 필요한 경우 바이트 제한으로 계산됩니다 (예 : 컴파일 라인이 gcc bomb.c -o bomb -O3 -lm인 경우 -O3 -lm부분 (7 바이트)이 계산됩니다 (초기 선행 공백은 계산되지 않음).
  • 프리 프로세서는 사용자 언어에 대한 표준 컴파일 옵션 인 경우에만 허용 됩니다 .
  • 환경은 귀하에게 달려 있지만,이를 검증 할 수 있도록하려면 최신 (즉, 사용 가능한) 컴파일러 버전과 운영 체제를 고수하십시오 (사용중인 시스템을 분명히 지정하십시오).
  • 오류없이 컴파일해야합니다 (경고는 괜찮습니다). 컴파일러 충돌은 아무것도 계산하지 않습니다.
  • 어떤 프로그램이 실제로 하는 일은 그것이 무엇이든 악성되지 않을 수 있지만, 관계가 없습니다. 시작할 필요조차 없습니다.

실시 예 1

C 프로그램

main(){return 1;}

Apple LLVM version 7.0.2 (clang-700.1.81)OS X 10.11 (64 비트)에서 컴파일 :

clang bomb.c -o bomb -pg

9228 바이트의 파일을 생성합니다. 총 소스 크기는 17 + 3 (의 경우 -pg) = 20 바이트이며 이는 크기 제한 내에 있습니다.

실시 예 2

Brainfuck 프로그램 :

++++++[->++++++++++++<]>.----[--<+++>]<-.+++++++..+++.[--->+<]>-----.--
-[-<+++>]<.---[--->++++<]>-.+++.------.--------.-[---<+>]<.[--->+<]>-.

다음을 사용하여 awib 로 c로 변환했습니다.

./awib < bomb.bf > bomb.c

그런 다음 Apple LLVM version 7.0.2 (clang-700.1.81)OS X 10.11 (64 비트)에서 컴파일됩니다 .

clang bomb.c

8464 바이트의 파일을 생성합니다. 여기에 총 입력은 143 바이트입니다 ( @lang_cwipe의 기본값이므로 소스 파일에 추가 할 필요가 없으며 명령에 특별한 플래그가 없습니다).

이 경우 임시 bomb.c 파일은 802 바이트이지만 소스 크기 나 출력 크기에 포함되지 않습니다.

최종 노트

4GB 이상의 출력이 달성되면 (아마 누군가 튜링 완료 전처리기를 발견 한 경우) 경쟁은 최소 크기의 파일을 생성하는 가장 작은 소스에 대한 경쟁이 될 것입니다 ( 너무 큰 제출을 테스트하는 것은 실용적이지 않습니다 ) .


트랜스 파일러를 사용하는 경우 출력 소스 코드와 입력 소스 코드가 512 바이트 미만이어야합니까?
trichoplax

3
반복적 인 트랜스 필이 허용됩니까?
orlp

3
@ LegionMammal978 예, 지정한 파일 형식 중 하나를 생성해야합니다. 그러나 당신이 해석 언어보다 더 가상적인 것을 발견했다고 생각한다면, 그것에 대해 구체적으로 물어보십시오. 가능할 것입니다. )를 개방의
데이브

3
@trichoplax 나는 그것을 알지 못했지만 일부 독서에서는 예처럼 보입니다. 파이썬 바이트 코드로 컴파일하는 것은 절대적으로 중요합니다. 따라서 파이썬의 경우 출력 크기는 모든 pyc / pyo 파일의 총 크기입니다. 이 주석 기반 업데이트로 질문을 곧 업데이트하겠습니다.
Dave

2
@MartinRosenau-WGroleau는 이미 비슷한 질문을했습니다. 챌린지가 시작될 때 이미 존재했던 모든 것을 사용할 수있는 챌린지 코딩의 표준입니다 .
Dave

답변:


441

C, (14 + 15) = 29 바이트 소스, 17,179,875,837 (16GB) 바이트 실행 가능

6 바이트를 해제 한 @viraptor에게 감사합니다.

2 바이트 오프 및 실행 가능 크기 x4에 대한 @hvd 덕분입니다.

이것은 main함수를 큰 배열로 정의 하고 첫 번째 요소를 초기화합니다. 따라서 GCC는 전체 실행 파일을 결과 실행 파일에 저장합니다.

이 배열은 2GB보다 크기 때문에 -mcmodel=mediumGCC에 플래그를 제공해야합니다 . 규칙에 따라 추가 15 바이트가 점수에 포함됩니다.

main[-1u]={1};

이 코드가 실행될 때 좋은 일을 할 것으로 기대하지 마십시오.

다음과 같이 컴파일하십시오.

gcc -mcmodel=medium cbomb.c -o cbomb

@ hvd의 제안을 테스트하고 처리하기에 충분한 주스가있는 기계를 찾는 데 시간이 걸렸습니다. 결국 10GB RAM, 12GB 스왑 및 / tmp가 큰 로컬 파티션으로 설정된 오래된 비 프로덕션 RedHat 5.6 VM을 발견했습니다. GCC 버전은 4.1.2입니다. 총 컴파일 시간은 약 27 분입니다.

CPU 및 RAM로드로 인해 원격 프로덕션 관련 시스템에서이 컴파일을 수행하지 않는 것이 좋습니다 .



13
나는 내 해결책에 맞서 싸우고 있지만 ... 필요하지 않습니다 a. 당신은 사용할 수 있습니다main[1<<30]={1};
viraptor

38
어머. 이것은 악하다. X는 그 코드를 컴파일하려고 몇 분 동안 얼었다. 나는 다른 컴퓨터가 ssh로 돌아가서 gcc 프로세스가 마침내 다시 돌아 오기 전에 죽일 수 있기를 시작했습니다. Btw. 당신보다 더 큰 값을 원하는 경우 1<<30다음 7<<28옵션이 될 수 있습니다.
kasperd

33
> 4GB? 즉 신속하게 에스컬레이션
웨인 베르너에게

18
다른 사람이 왜 이것이 컴파일되는지 궁금해하는 경우 : stackoverflow.com/questions/34764796/…
TC

206

C #, 컴파일하는 데 약 1 분, 28MB 출력 바이너리 :

class X<A,B,C,D,E>{class Y:X<Y,Y,Y,Y,Y>{Y.Y.Y.Y.Y.Y.Y.Y.Y y;}}

Y를 더 추가하면 크기가 기하 급수적으로 증가합니다.

@Odomontois의 요청에 따라 Pharap의 설명 :

이 답변은 재귀를 만들기 위해 상속 및 형식 매개 변수를 남용합니다. 무슨 일이 일어나고 있는지 이해하려면 먼저 문제를 단순화하는 것이 더 쉽습니다. 내부 클래스가있는 class X<A> { class Y : X<Y> { Y y; } }일반 클래스를 생성하는 것을 고려하십시오 . 상속 , 따라서 또한 내부 클래스 가지고 다음이다 . 그러면 내부 클래스도 있고 내부 클래스 에는 내부 클래스 등이 있습니다. 즉, 범위 확인 ( ) 광고 무한대를 사용할 수 있으며이를 사용할 때마다 컴파일러는 다른 수준의 상속 및 형식 매개 변수화를 추론해야합니다. .X<A>YX<A>.YX<Y>X<A>.YYX<A>.Y.YYYY.

유형 매개 변수를 추가하면 컴파일러가 각 단계에서 수행해야하는 작업이 더욱 증가합니다.

다음과 같은 경우를 고려하십시오
. class X<A> { class Y : X<Y> { Y y;} }유형 param A의 유형은 X<A>.Y입니다.
에서 class X<A> { class Y : X<Y> { Y.Y y;} }형 PARAM A의 유형이있다 X<X<A>.Y>.Y.
에서 class X<A> { class Y : X<Y> { Y.Y.Y y;} }형 PARAM A의 유형이있다 X<X<X<A>.Y>.Y>.Y.
에서 class X<A,B> { class Y : X<Y,Y> { Y y;} }유형 PARAM가 A있습니다 X<A,B>.YB입니다 X<A,B>.Y.
에서 class X<A> { class Y : X<Y> { Y.Y y;} }유형 PARAM가 A있습니다 X<X<A,B>.Y, X<A,B>.Y>.YB입니다 X<X<A,B>.Y, X<A,B>.Y>.Y.
에서 class X<A> { class Y : X<Y> { Y.Y.Y y;} }유형 PARAM가 A있습니다 X<X<X<A,B>.Y, X<A,B>.Y>.Y, X<X<A,B>.Y, X<A,B>.Y>.Y>.YB입니다 X<X<X<A,B>.Y, X<A,B>.Y>.Y, X<X<A,B>.Y, X<A,B>.Y>.Y>.Y.

이 패턴에 따라, 하나는 상상할 수 1 컴파일러는 무엇을 추론하기 위해 수행해야 일 A하기 EY.Y.Y.Y.Y.Y.Y.Y.Y정의에 class X<A,B,C,D,E>{class Y:X<Y,Y,Y,Y,Y>{Y.Y.Y.Y.Y.Y.Y.Y.Y y;}}.

1 알아낼 수는 있지만 많은 인내심이 필요하며 인텔리전스가 도움이되지 않습니다.


14
이것은 내가 기대했던 광기와 비슷합니다! Mono를 다시 설치하지 않은 것 같습니다…
Dave

31
그러한 악명 높은 효과에 대한 설명을 제공해 줄 수 있습니까?
Odomontois

16
단순히 큰 배열을 초기화하는 것 이상을 수행하면 +1됩니다.
Stig Hemmer

6
다음은 Try Roslyn 및 3 Ys 를 사용하는 예 입니다.
Kobi

10
나는이 질문을보고 즉시 당신을 생각했습니다. 좋은!
Eric Lippert

154

Python 3, 13 바이트 소스, 9,057,900,463 바이트 (8.5GiB) .pyc-file

(1<<19**8,)*2

편집 : 4GiB 이상의 출력 크기가 중요하지 않다는 규칙을 깨달은 후 코드를 위의 버전으로 변경했습니다.이 코드는 약간 짧습니다. 이전 코드와 더 중요한 설명은 아래에서 찾을 수 있습니다.


Python 3, 16 바이트 소스,> 32TB .pyc 파일 (메모리, 디스크 공간 및 인내심이 충분한 경우)

(1<<19**8,)*4**7

설명 : Python 3은 일정한 접힘을 수행하며 지수를 사용하면 큰 숫자를 빠르게 얻을 수 있습니다. .pyc 파일이 사용하는 형식은 4 바이트를 사용하여 정수 표현의 길이를 저장하지만 실제로 한계는 더 비슷해 보입니다. 2**31지수를 사용하여 하나의 큰 숫자를 생성하면 한계는 2GB를 생성하는 것으로 보입니다. 8 바이트 소스의 pyc 파일 ( 19**8비트 수줍음 8*2**31이어서 1<<19**82GB 미만의 이진 표현이 있습니다 .8을 곱하면 비트가 아닌 바이트를 원하기 때문입니다)

그러나 튜플도 변경할 수 없으며 튜플을 곱하는 것도 일정하게 접히므로 2GB 얼룩을 원하는 횟수만큼 복제 할 수 있습니다 2**31. 는 4**7그것이 내가 그 이전 16TB의 답을 이길 찾을 수있는 최초의 지수가 있었다해서 선택되었다 32TB에 도착합니다.

불행히도, 나는 내 컴퓨터에 가지고있는 메모리로 이것을 2의 승수까지만 테스트 할 수 있습니다. (1<<19**8,)*28.5GB 파일을 생성하여 답변이 현실적임을 보여주기를 바랍니다 (예 : 파일 크기가 2 ** 32 = 4GB로 제한되지 않음).

또한 테스트 할 때 얻은 파일 크기가 예상 한 4GB가 아닌 8.5GB 인 이유를 알 수 없으며 파일 크기가 커서 주변을 파고 들지 않을 정도로 충분히 큽니다.


2
+1, 왜 그렇지 (1<<19**8,)*2않습니까? 4GB면 충분합니다.
Akangka

2
@ChristianIrwan : 그래, 나는 그 규칙을 잊어 버렸고, 몇 분 전에 그것을 깨달았고, 어떤 종류의 편집을 아직해야하는지 알지 못했다. :-)
Aleksi Torhamo 2016 년

1
좋은. 이것은 13 바이트에 불과하므로 마침내 첫 번째 게시 된 답변에 도전자가 있습니다! 1<<18내 컴퓨터 (1.5GB) 에서만 확인할 수 있었지만 나중에 Linux에서 테스트하여 전체 8GB (32TB 버전을 사용하지 않을 것입니다!)에서 작동 할 것으로 예상합니다.
Dave

1
@Dave : 정확한 크기는 버전에 따라 다를 수 있습니다 (하지만 1.5GB는 이상하게 들립니다). Python 3.3.5를 사용 python -m py_compile asd.py하고 .pyc 파일을 생성하는 데 사용 되었습니다.
Aleksi Torhamo

3
IIRC, 파이썬은 정수 표현에서 32 비트 워드 당 30 비트를 사용합니다.

130

4GB 이상의 출력이 달성되면 (아마 누군가 튜링 완료 전처리기를 발견 한 경우) 경쟁은 최소 크기의 파일을 생성하는 가장 작은 소스에 대한 경쟁이 될 것입니다 (너무 큰 제출을 테스트하는 것은 실용적이지 않습니다) .

"템플릿 Haskell"을 사용하면 Haskell을 사용하여 컴파일시 Haskell 코드를 생성 할 수 있으므로 완전한 전 처리기입니다.

다음은 임의의 숫자 식으로 매개 변수화 된 내 시도입니다 FOO.

import Language.Haskell.TH;main=print $(ListE .replicate FOO<$>[|0|])

마법은 "splice"내부의 코드 $(...)입니다. 이것은 컴파일 시점에 실행되어 Haskell AST를 생성하며, 스플 라이스 대신 프로그램의 AST에 접목됩니다.

이 경우, 우리는 문자를 나타내는 간단한 AST을 0, 우리는이 복제 FOO우리는 사용 목록을 만들기 위해 시간 ListE으로부터 Language.Haskell.TH리터럴을 나타내는 하나의 큰 AST로하는 AST의 목록을 설정하는 모듈 [0, 0, 0, 0, 0, ...].

결과 프로그램은의 반복 main = print [0, 0, 0, ...]과 동일합니다 .FOO0

ELF로 컴파일하려면 :

$ ghc -XTemplateHaskell big.hs
[1 of 1] Compiling Main             ( big.hs, big.o )
Linking big ...
$ file big
big: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /nix/store/mibabdfiaznqaxqiy4bqhj3m9gaj45km-glibc-2.21/lib/ld-linux.so.2, for GNU/Linux 2.6.32, not stripped

길이는 83 바이트 (하스켈 코드의 경우 66, -XTemplateHaskell인수의 경우 17 )이며 길이는 FOO입니다.

우리는 컴파일러 인수를 피하고 그냥로 컴파일 할 수 ghc있지만 {-# LANGUAGE TemplateHaskell#-}처음에는 코드를 97 바이트까지 늘려야합니다.

다음은에 대한 몇 가지 예제 표현식 FOO과 결과 바이너리의 크기입니다.

FOO         FOO size    Total size    Binary size
-------------------------------------------------
(2^10)      6B          89B           1.1MB
(2^15)      6B          89B           3.6MB
(2^17)      6B          89B           12MB
(2^18)      6B          89B           23MB
(2^19)      6B          89B           44MB

로 컴파일하는 RAM이 부족 (2^20)합니다.

repeat대신을 사용하여 무한 목록을 만들 수도 replicate FOO있지만 컴파일러는 정지하지 않습니다.)


46
프로그래밍 퍼즐과 코드 골프에 오신 것을 환영합니다. 이것은 특히이 사이트를 처음 사용하는 사용자 에게는 훌륭한 답변입니다. 도움이 필요하면 (의문의 여지없이) 언제든지 문의하십시오.
wizzwizz4

3
@ wizzwizz4 : 네, 훌륭한 답변입니다. Haskell에서는 메타 프로그래밍 작업을 수행하기 위해 특별한 컴파일러 지시문이 필요하다는 점을 제외하면 본질적으로 내 것과 동일합니다. ;)
Mason Wheeler

2
GHC 7.8.3으로 컴파일하면 "Not in scope : '<$>'"가 표시됩니다 (코드를로 설정 [...].replicate (2^10)<$>[|0|])). 나는 Haskell에 경험이 없습니다. 컴파일하는 방법에 대한 힌트가 있습니까?
Dave

38
잘못된 템플릿 haskell은 무한 실행 파일을 스트리밍하기에 게으르지 않습니다.
PyRulez

1
안녕하세요 @Dave이 <$>기능은 Haskell에서 널리 사용되지만 GHC 7.10에서는 "prelude"(기본적으로 사용 가능한 기능 세트)로만 이동되었습니다. 이전 버전 import Control.Applicative;에서는 exising import문 다음 에 추가해야 합니다. 방금 GHC 7.8.4로 시도했지만 작동합니다.
Warbo

80

C ++, 250 + 26 = 276 바이트

template<int A,int B>struct a{static const int n;};
template<int A,int B>const int a<A,B>::n=a<A-1,a<A,B-1>::n>::n;
template<int A>struct a<A,0>{static const int n=a<A-1,1>::n;};
template<int B>struct a<0,B>{static const int n=B+1;};
int h=a<4,2>::n;

이것은이다 아커 만 함수 템플릿에서 구현. h=a<4,2>::n;작은 (6GB) 컴퓨터에서 컴파일 할 수 없지만 h=a<3,14>26M 출력 파일을 관리 했습니다. 상수를 조정하여 플랫폼의 한계에 도달 할 수 있습니다. 링크 된 Wikipedia 기사를 참조하십시오.

-gGCC에 대한 플래그가 필요합니다 (실제로 공간을 소비하는 모든 디버그 기호이기 때문에). 내 컴파일 라인은 다음과 같이 끝났습니다.

g++ -ftemplate-depth=999999 -g -c -o 69189.o 69189.cpp

플랫폼 정보

g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2
Linux 3.13.0-46-generic #79-Ubuntu SMP x86_64 GNU/Linux

나는 이것을 정말로 좋아하지만 ELF / .exe / etc라고 말했기 때문에 .o 출력을 수락 할 수 있는지 확실하지 않습니다. (컴파일하면 완전히 최적화됩니다!). 여전히 +1 (확인)
Dave

4
업데이트 : 벤 보이트는 그의 대답에서 지적한 것처럼, 리눅스 GCC는 않습니다 .o 인 출력으로 ELF 파일을 생성, 난 그래 그래서, 그와 함께 <3,14> 변형을 확인 할 수있었습니다 -이 유효합니다.
Dave

17
나는 C ++ 템플릿에서 뭔가 터무니없는 것을 기대하고있었습니다. 나는 되지 않은 아커 만 함수를 기대.
Mark

피보나치가 더 작은 코드와 더 나은 출력 크기 제어를 제공하지 않습니까?
Will Ness

1
그러나 우리는 더 큰 코드를 원합니다! 피보나치는 순수한 선형 코드와 거의 같은 크기를 제공하지만 선형 컴파일 시간은 더 길다. 당신은 확실히 A+B각 클래스에서 정적 크기의 배열로 재미를 가질 수 있습니다 . 이제 생각합니다 ...
Toby Speight

65

ASM, 61 바이트 (소스 29 바이트, 플래그 32 바이트), 4,294,975,320 바이트 실행 가능

.globl main
main:
.zero 1<<32

와 컴파일 gcc the_file.s -mcmodel=large -Wl,-fuse-ld=gold


5
1<<30C에 충분합니다. 이것은 어셈블러이므로 크기는 바이트입니다.
viraptor

2
@viraptor 내 시스템에는 32GB의 RAM이 있으며 차기에는 코드를 작성하려고했습니다. as에 전달 ld하지만 이것으로 ld실패 합니다 . -mcmodel=medium도움이 되지 않는 것 같습니다.
Idonotexist Idonotexist

2
gold링커 사용 강제 시도 : gcc -fuse-ld=gold ...컴파일 / 링크 ... eek! 1:29 (89 초) 및 1,073,748,000 바이트 크기로 완료되었습니다.
lornix

2
마침내 이것을 호출하여 64 비트 Ubuntu 15.10에 조립했습니다 gcc -o g g.s -mcmodel=large -Wl,-fuse-ld=gold. 마지막 집계 : 4,294,975,320 bytes,에 대한 프로그램 길이에 32 바이트가 추가되었습니다 -mcmodel=large -Wl,-fuse-ld=gold. 헤더가 잘못되었다는 점에 주목할 가치가 있습니다. 소스는 29 바이트입니다 (추가 플래그는 추가되지 않음).
Mego

3
할당을 최대로 늘려서 바이트 실행 파일로 1<<33끝났습니다 8,589,942,616.
Mego

60

다음은 2005 년의 C 답변입니다. 16TB RAM이있는 경우 16TB 바이너리를 생성합니다 (그렇지 않은 경우).

struct indblock{
   uint32_t blocks[4096];
};

struct dindblock {
    struct indblock blocks[4096];
};

struct tindblock {
    struct dindblock blocks[4096];
};

struct inode {
    char data[52]; /* not bothering to retype the details */
    struct indblock ind;
    struct dindblock dint;
    struct tindblock tind;
};

struct inode bbtinode;

int main(){}

19
"16TB RAM이 있다면 16TB 바이너리를 생산할 수 있습니다." -16TB 하드 드라이브도 없습니다! 나는 이것을 정말로 확인할 수 없지만 그럼에도 불구하고 시원합니다.
Dave

5
우연히이 것을 발견하고 주소 공간이 부족할 때 컴파일러가 넘어지는 것을 보았습니다.
Joshua

8
이 항목을 골프화하려고 시도하지 마십시오. 골프는 코드 샘플의 의도를 잃고 그렇게함으로써 점수 이점이 없습니다. 코드는 이미 2005 년 현재 GPL입니다.
Joshua

6
@BenVoigt 어쨌든 다른 사람들의 코드를 편집하는 것은 결코 허용되지 않습니다. 문제가 있으면 의견을 남겨주세요. 관련 메타 포스트 : meta.codegolf.stackexchange.com/questions/1615/…
Mego

2
@Joshua : 마크 다운 차이를 확인하십시오. Mego는 강조 힌트 만 추가했습니다.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

25

일반 C 프리 프로세서 : 214 바이트 입력, 5MB 출력

실제 전처리기에 영감을 얻었 습니다 .

#define A B+B+B+B+B+B+B+B+B+B
#define B C+C+C+C+C+C+C+C+C+C
#define C D+D+D+D+D+D+D+D+D+D
#define D E+E+E+E+E+E+E+E+E+E
#define E F+F+F+F+F+F+F+F+F+F
#define F x+x+x+x+x+x+x+x+x+x

int main(void) { int x, y = A; }

실험에 따르면 각 수준의 #defines가 예상대로 출력을 약 10 배 더 크게 만듭니다. 그러나이 예제는 컴파일하는 데 1 시간 이상이 걸렸으므로 결코 "G"로 넘어 가지 않았습니다.


9
이것은 XML을 폭탄처럼 좀있다
집게 벌레

9
구체적으로 이것은 원래 "Billion Laughs"의 구현입니다.
mınxomaτ

이것은 미쳤지 만 간단합니다.
Vahid Amiri

2
와우, 이것은 실제로 GCC 4.9와 Clang에서 segfault를 일으 킵니다. 어떤 컴파일러를 사용 했습니까?
Dave

1
@ 데이브 : 이상합니다. make를 사용하여 컴파일하면 컴파일되지만 make가 사용하는 것과 동일한 명령을 입력하면 충돌이 발생합니다. 그리고 환경 변수와 관련이없는 것 같습니다.
Thomas Padron-McCarthy

24

Java, 450 + 22 = 472 바이트 소스, ~ 1GB 클래스 파일

B.java (골프 버전, 컴파일 중 경고)

import javax.annotation.processing.*;@SupportedAnnotationTypes("java.lang.Override")public class B extends AbstractProcessor{@Override public boolean process(java.util.Set a,RoundEnvironment r){if(a.size()>0){try(java.io.Writer w=processingEnv.getFiler().createSourceFile("C").openWriter()){w.write("class C{int ");for(int i=0;i<16380;++i){for(int j=0;j<65500;++j){w.write("i");}w.write(i+";int ");}w.write("i;}");}catch(Exception e){}}return true;}}

B. 자바 (ungolfed 버전)

import java.io.Writer;
import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement;

@SupportedAnnotationTypes("java.lang.Override")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class B extends AbstractProcessor {
    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        if (annotations.size() > 0) {
            try (Writer writer = processingEnv.getFiler().createSourceFile("C").openWriter()) {
                writer.write("class C{int ");
                for (int i = 0; i < 16380; ++i) {
                    for (int j = 0; j < 65500; ++j) {
                        writer.write("i");
                    }
                    writer.write(i + ";int ");
                }
                writer.write("i;}");
            } catch (Exception e) {
            }
        }
        return true;
    }
}

편집

javac B.java
javac -J-Xmx16G -processor B B.java

설명

이 폭탄은 주석 처리기를 사용합니다. 컴파일 패스가 2 개 필요합니다. 첫 번째 패스는 프로세서 클래스를 빌드합니다 B. 두 번째 단계에서 프로세서는 새로운 소스 파일을 생성하고 C.java이를 바이트 C.class크기로 컴파일합니다 1,073,141,162.

큰 클래스 파일을 만들 때 몇 가지 제한 사항이 있습니다.

  • 약 64k보다 긴 식별자를 만들면 다음이 발생 error: UTF8 representation for string "iiiiiiiiiiiiiiiiiiii..." is too long for the constant pool합니다.
  • 약 64k 개 이상의 변수 / 함수를 만들면 다음과 같은 결과가 발생합니다. error: too many constants
  • 함수의 코드 크기에 대한 제한은 약 64k입니다.
  • Java 컴파일러에는 .class파일 에 대한 약 1GB의 일반적인 제한 (버그?)이있는 것 같습니다 . 나는이 증가하는 경우 1638016390위의 코드에서 컴파일러는 반환하지 않습니다.
  • 또한 .java파일 에 대한 약 1GB의 제한이 있습니다. 위의 코드에서 증가 16380하면 다음과 같이 나타납니다 .16400An exception has occurred in the compiler (1.8.0_66). Please file a bug ...java.lang.IllegalArgumentException

10
산뜻한; 기본적으로 사용자 지정 전처리기를 지원하는 컴파일러가있는 언어로 크기 제한 내에서 자체 전처리기를 만들었습니다. 규칙 안에 있습니다. 마지막 수업은 0.5GB 였지만 방법을 확인할 수 있습니다.
Dave

Java habrahabr.ru/post/245333의 또 다른 예 -중첩을 사용합니다 try..finally(마지막으로 예외적 인 경우 중복 된 코드의 코드 가 중첩 됨 ) 및 초기화 블록 (이니셜 라이저 블록의 코드가 각 생성자에
Victor

나는 대체 ä에 의해 i및 숫자를 조정. 이제 폭탄은 인코딩 문제없이 모든 시스템에서 1GB 클래스를 만들어야합니다. 그러나 이제는 더 많은 메모리가 필요합니다.
Sleafar

? TypeElement를 확장합니까?!?
고양이


22

C, 26 바이트 소스, 2,139,103,367 바이트 출력, 유효한 프로그램

const main[255<<21]={195};

다음을 사용하여 컴파일 : gcc cbomb.c -o cbomb(gcc 버전 4.6.3, Ubuntu 12.04, ~ 77 초)

명령 줄 옵션을 사용하지 않고 유효한 프로그램을 얼마나 크게 만들 수 있는지 알고 싶었습니다. 이 답변에서 아이디어를 얻었습니다 : Digital Trauma의 https://codegolf.stackexchange.com/a/69193/44946 . 이것이 컴파일되는 이유에 대한 의견을 참조하십시오.

작동 방식 : const세그먼트의 페이지에서 쓰기 플래그를 제거하므로 main을 실행할 수 있습니다. 는 195반환 용 인텔 머신 코드입니다. 인텔 아키텍처는 리틀 엔디안이므로 첫 번째 바이트입니다. 프로그램은 eax 레지스터에 넣은 시작 코드 (0 일 가능성이있는)로 종료됩니다.

링커가 오프셋에 32 비트 부호있는 값을 사용하기 때문에 약 2 기가입니다. 컴파일러 / 링커가 작동하려면 약간의 공간이 필요하기 때문에 2 기가보다 8 메가 작습니다. 이것은 링커 오류없이 얻을 수있는 가장 큰 크기입니다-ymmv.


3
흥미로운 것은 출력은 최대 압축 = 1029 : 1 압축 비율로 압축 된 2,078,451 바이트입니다.
Zakipu

20

, 71 바이트. 컴파일 시간 : 9 분 134,222,236 바이트 실행 가능

macro R(e as int):
 for i in range(2**e):yield R.Body
x = 0
R 25:++x

매크로 R(반복 용)를 사용하여 컴파일러가 incremental 문에 임의의 횟수를 곱하게합니다. 특별한 컴파일러 플래그는 필요하지 않습니다. 파일을 다른 이름으로 저장하고 bomb.boo컴파일러를 호출하여 booc bomb.boo빌드하십시오.


2**e-이게 뭐야? 시도하십시오 9**e!
wchargin 님은

1
@WChargin : 메타 프로그래밍의 재미있는 점은 메타 데이터를 쉽게 사용자 지정할 수 있다는 것입니다!
메이슨 휠러

boo를 설치하는 데 약간의 문제가 있습니다. 설치를 관리 할 때 확인하겠습니다!
Dave

@ 데이브 무슨 문제가 있습니까?
메이슨 휠러

16

Kotlin , 90 바이트 소스, 177416 바이트 (173KB) 컴파일 된 JVM 바이너리

inline fun a(x:(Int)->Any){x(0);x(1)}
fun b()=a{a{a{a{a{a{a{a{a{a{a{println(it)}}}}}}}}}}}

기술적으로 표현식을 더 중첩하여 더 길게 만들 수 있습니다. 그러나 StackOverflow재귀를 늘리면 컴파일러에서 오류가 발생합니다.


SI 접두사가 동의하지 않습니다. 177416 킬로바이트 = 173MB 또는 177416 바이트 = 173kB입니까?
벤 Voigt

1
@BenVoigt 다음을 지적 해 주셔서 감사합니다. : D
TheNumberOne

인상적, +1
J Atkin

Kotlin 1.2.20을 컴파일하려면 깊이를 제거해야하며 ~ 104kB입니다. 원래 어떤 버전을 사용하셨습니까?
TWiStErRob

15

C ++, 214 바이트 (특수 컴파일 옵션 필요 없음)

#define Z struct X
#define T template<int N
T,int M=N>Z;struct Y{static int f(){return 0;}};T>Z<N,0>:Y{};T>Z<0,N>:Y{};T,int M>Z{static int f(){static int x[99999]={X<N-1,M>::f()+X<N,M-1>::f()};}};int x=X<80>::f();

그것은 매우 간단한 2 차원 템플릿 재귀입니다 (재귀 깊이는 방출 된 총 템플릿의 제곱근이므로 플랫폼 한계를 초과하지 않음). 각각의 작은 정적 데이터가 있습니다.

생성 된 오브젝트 파일 g++ 4.9.3 x86_64-pc-cygwin은 2567355421 바이트 (2.4GiB)입니다.

초기 값을 80 이상으로 높이면 cygwin gcc 어셈블러가 손상됩니다 (너무 많은 세그먼트).

또한 소스 코드를 변경하지 않고 크기를 늘리기 위해 99999대체 9<<19하거나 이와 비슷한 크기 로 대체 할 수 있습니다 ...하지만 이미 디스크 공간을 더 이상 사용할 필요는 없다고 생각합니다.)


확인되었지만 (실제로 clang이있는 2.56GB입니다) -c링커를 중지하려면 컴파일 플래그가 필요합니다 (2 바이트), 나는 .o 출력 (내가 나열된 것 중 하나가 아님)을 수락 할 수 있는지 확실하지 않습니다. 여전히, 나는 그것을 좋아하므로 +1.
Dave

@Dave : gcc .o 파일은 ELF 형식이 아닙니까?
Ben Voigt

확실하지 않다. ELF 매직 넘버로 시작하지는 않습니다. 나중에 조사하겠습니다.
Dave

@Dave : cygwin gcc는 ELF 파일을 생성하지 않습니다. Linux gcc는 (다른 코드에서 하나를보고 있지만)
Ben Voigt

예, Kubuntu의 GCC 5.2.1은 실제로 ELF 파일을 생성하지만 9MB에 불과합니다! 다른 컴파일러와 비교하여 압축 방법이 확실하지 않습니다. 아마도 GCC 4.9는 2GB ELF 파일을 만들 것입니다.
Dave

6

스칼라-70 바이트 소스, 22980842 바이트 결과 (jar 후)

import scala.{specialized => s}
class X[@s A, @s B, @s C, @s D, @s E]

이 9 생산 5 약 23 메가 바이트 항아리에 팩 (약 59,000) 전문 클래스 파일을. 많은 파일과 충분한 메모리를 처리 할 수있는 파일 시스템이 있다면 원칙적으로 계속 진행할 수 있습니다.

jar 명령이 포함되어야하는 경우 82 바이트입니다.


나는 그것을 컴파일 할 수 없었다 : error: java.lang.OutOfMemoryError: GC overhead limit exceeded. 컴파일에 필요한 명령을 문서화 할 수 있습니까?
P.Peter

@ P.Péter-컴파일러에 더 많은 메모리를 제공해야합니다 scalac -J-Xmx12G X.scala. 예를 들어 내가 사용한 것과 같습니다. 실제로 실제로 얼마나 필요한지는 테스트하지 않았습니다.
Rex Kerr

여전히 슬프게도 :( 컴파일하지 error: error while loading AnnotatedElement, class file '/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/rt.jar(java/lang/reflect/AnnotatedElement.class)' is broken (bad constant pool tag 18 at byte 76) one error found? 당신은 스칼라와 자바 버전 (너무 어쩌면 플랫폼을)를 지정할 수 있습니까 데비안 8 - 64에 scalac 2.9.2 및 오픈 JDK 1.8.0_66-내부-B17를 사용했다.
P.Péter

우분투 15.10, java version "1.8.0_72-ea" Java(TM) SE Runtime Environment (build 1.8.0_72-ea-b05) Java HotSpot(TM) 64-Bit Server VM (build 25.72-b05, mixed mode) ,$ scala -version Scala code runner version 2.11.7 -- Copyright 2002-2013, LAMP/EPFL
렉스 커

2

C, 284 바이트 + 2 대 -cgcc bomb.c -o bomb.o -c; 출력 : 2147484 052 바이트

#define a 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
#define b a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a
#define c b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b
#define d c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c
#define e d,d,d,d,d,d,d,d,d,d,d,d,d,d,d,d
#define f e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e
__int128 x[]={f,f,f,f,f,f,f,f};

0

부, 이것보다 더 많은 것을 기대할 수 있습니다

macro R(e as int):for i in range(9**e):yield R.Body
x = 0
R 99:++x

이것은 약간의 작은 변화 (??)가있는 Mason Wheeler의 대답처럼 보입니다. 동일한 답변에 독립적으로 도달했거나 변경 한 값에 중요한 것이 있습니까? (그렇다면 중요한 이유를 설명하기 위해 답변을 편집하십시오)
Dave

0

파이썬 3 :

9**9**9**9**9

테트 레이션 폭탄


2
입력이 다른 바이트와 어떻게 비교되는지 보려면 출력 바이트 수를 표시해야합니다.
Sanchises

PPCG에 오신 것을 환영합니다! 실수로 두 개의 계정을 만들고이 답변을 두 번 게시 한 것 같습니다. 다른 답변을 제거했습니다. Sanchises가 말했듯이,이 과제는 컴파일 된 프로그램 의 크기에 따라 점수가 매겨집니다 . 따라서 기본 점수이므로 답에 해당 크기를 포함시켜야합니다. 또한 실제 프로그램은 그리 크지 않고 메모리에서 생성하는 표현 만 있으므로 다른 접근법에 대해 생각할 수도 있습니다.
마틴 엔더

1
@MartinEnder 파이썬이 컴파일 타임에 일부 표현식을 평가하고 임의의 정밀도로 숫자를 저장하는 방식으로 인해 이론적으로는 큰 실행 파일이 있습니다. 그러나 Aleksi Torhamo (자신의 답변의 일부로 동일한 기술을 사용)가 지적한 것처럼, 이것은 2GB 정도의 한계가 있으므로 작성된 코드는 컴파일되지 않을 것으로 예상됩니다 (확인하지는 않았지만) ). OP가 컴파일하고 컴파일 된 크기를 게시하는 데 필요한 명령과 함께 컴파일 된 크기를 게시 할 수 있으면 유효합니다. Aleksi의 기존 답변과의 유사성은 나에게 우연의 일치로 보입니다.
Dave
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.