Bangun Bom Kompiler


372

pengantar

Anda mungkin akrab dengan bom ritsleting , bom XML , dll. Sederhananya, mereka adalah (relatif) file kecil yang menghasilkan output yang sangat besar ketika ditafsirkan oleh perangkat lunak naif. Tantangannya di sini adalah menyalahgunakan kompiler dengan cara yang sama.

Tantangan

Tulis beberapa kode sumber yang menempati 512 byte atau kurang dan yang dikompilasi menjadi file yang menempati ruang paling mungkin. File output terbesar menang!

Aturan

OK, jadi ada beberapa klarifikasi, definisi, dan batasan penting;

  • Output dari kompilasi harus berupa file ELF , Windows Portable Executable (.exe), atau bytecode virtual untuk JVM atau .Net's CLR (jenis bytecode virtual lain juga cenderung OK jika diminta). Pembaruan: Output .pyc / .pyo Python juga diperhitungkan .
  • Jika bahasa pilihan Anda tidak dapat dikompilasi secara langsung ke dalam salah satu format tersebut, transpilasi diikuti oleh kompilasi juga diperbolehkan ( Perbarui: Anda dapat mentranspilasikan beberapa kali, asalkan Anda tidak pernah menggunakan bahasa yang sama lebih dari sekali ).
  • Kode sumber Anda dapat terdiri dari beberapa file, dan bahkan file sumber daya, tetapi ukuran total semua file ini tidak boleh melebihi 512 byte.
  • Anda tidak dapat menggunakan input selain dari file sumber Anda dan perpustakaan standar bahasa pilihan Anda. Menghubungkan statis perpustakaan standar adalah OK jika didukung. Secara khusus, tidak ada perpustakaan pihak ketiga atau perpustakaan OS.
  • Harus dimungkinkan untuk menjalankan kompilasi Anda menggunakan perintah atau serangkaian perintah. Jika Anda memerlukan tanda tertentu saat dikompilasi, ini dihitung menuju batas byte Anda (mis. Jika garis kompilasi Anda gcc bomb.c -o bomb -O3 -lm, -O3 -lmbagian (7 byte) akan dihitung (perhatikan ruang awal awal tidak dihitung).
  • Pra-prosesor hanya diizinkan jika mereka merupakan opsi kompilasi standar untuk bahasa Anda.
  • Lingkungan terserah pada Anda, tetapi demi kepentingan membuat hal ini dapat diverifikasi, patuhi versi kompiler dan sistem operasi terbaru (yaitu yang tersedia) (dan jelas tentukan yang Anda gunakan).
  • Itu harus dikompilasi tanpa kesalahan (peringatan OK), dan menabrak kompiler tidak menghitung apa pun.
  • Apa yang sebenarnya dilakukan oleh program Anda tidak relevan, meskipun tidak bisa berupa apa pun yang berbahaya. Bahkan tidak harus bisa memulai.

Contoh 1

Program C.

main(){return 1;}

Dikompilasi dengan Apple LLVM version 7.0.2 (clang-700.1.81)pada OS X 10.11 (64-bit):

clang bomb.c -o bomb -pg

Menghasilkan file sebesar 9228 byte. Ukuran sumber total adalah 17 + 3 (untuk -pg) = 20 byte, yang mudah dalam batas ukuran.

Contoh 2

Program Brainfuck:

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

Diubah dengan awib ke c dengan:

./awib < bomb.bf > bomb.c

Kemudian dikompilasi dengan Apple LLVM version 7.0.2 (clang-700.1.81)pada OS X 10.11 (64-bit):

clang bomb.c

Menghasilkan file 8464 byte. Input total di sini adalah 143 byte (karena @lang_cmerupakan default untuk awib, ia tidak perlu ditambahkan ke file sumber, dan tidak ada flag khusus pada kedua perintah).

Juga perhatikan bahwa dalam kasus ini, file bomb.c sementara adalah 802 byte, tetapi ini tidak memperhitungkan ukuran sumber maupun ukuran output.

Catatan Akhir

Jika output lebih dari 4GB tercapai (mungkin jika seseorang menemukan preprocessor lengkap turing), kompetisi akan menjadi sumber terkecil yang menghasilkan file sekurang-kurangnya sebesar itu (tidak praktis untuk menguji pengiriman yang terlalu besar) .


Jika menggunakan transpiler, apakah kode sumber output harus di bawah 512 byte dan juga kode sumber input?
trichoplax

3
Apakah transpilasi berulang diperbolehkan?
orlp

3
@ LegionMammal978 ya itu harus menghasilkan salah satu jenis file yang saya tentukan. Tetapi jika Anda berpikir Anda telah menemukan sesuatu yang lebih dari mesin virtual daripada bahasa yang ditafsirkan, tanyakan tentang hal itu secara khusus dan itu mungkin saya akan mengizinkannya (itu agak subjektif sehingga saya ingin menjadi sangat terbatas untuk memulai, dengan opsi ini membuka itu)
Dave

3
@trichoplax Saya tidak menyadarinya, tetapi dari beberapa bacaan sepertinya ya; mengkompilasi bytecode Python benar-benar diperhitungkan. Jadi untuk python, ukuran output akan menjadi jumlah total ukuran semua file pyc / pyo Anda. Saya akan segera memperbarui pertanyaan dengan pembaruan berbasis komentar ini.
Dave

2
@MartinRosenau - WGroleau sudah mengajukan pertanyaan serupa; itu standar dalam pengkodean tantangan bahwa Anda dapat menggunakan apa pun yang sudah ada saat tantangan dimulai.
Dave

Jawaban:


441

C, (14 + 15) = 29 byte sumber, 17.179.875.837 (16 GB) byte dieksekusi

Berkat @viraptor untuk 6 byte.

Berkat @hvd untuk 2 byte dan ukuran x4 yang dapat dieksekusi.

Ini mendefinisikan main fungsi sebagai array besar dan menginisialisasi elemen pertamanya. Ini menyebabkan GCC untuk menyimpan seluruh array di executable yang dihasilkan.

Karena array ini lebih besar dari 2GB, kami perlu menyediakan -mcmodel=mediumflag ke GCC. 15 byte tambahan termasuk dalam skor, sesuai aturan.

main[-1u]={1};

Jangan berharap kode ini melakukan hal yang baik saat dijalankan.

Kompilasi dengan:

gcc -mcmodel=medium cbomb.c -o cbomb

Butuh beberapa saat untuk memeriksa saran @ hvd - dan menemukan mesin dengan jus yang cukup untuk menanganinya. Akhirnya saya menemukan RedHat 5.6 VM non-produksi lama dengan 10GB RAM, 12GB swap, dan / tmp diatur ke partisi lokal besar. Versi GCC adalah 4.1.2. Total waktu kompilasi sekitar 27 menit.

Karena beban CPU dan RAM, saya sarankan jangan melakukan kompilasi ini pada mesin yang berhubungan dengan produksi jarak jauh .



13
Saya bermain melawan solusi saya di sini, tapi ... Anda tidak perlu a. Anda bisa menggunakanmain[1<<30]={1};
viraptor

38
Astaga. Ini jahat. X membeku selama beberapa menit mencoba mengkompilasi kode itu. Saya mulai mencari komputer lain untuk ssh kembali dan mematikan proses gcc sebelum akhirnya hidup kembali. Btw. Jika Anda menginginkan nilai yang lebih besar 1<<30maka 7<<28bisa menjadi pilihan.
kasperd

33
> 4GB? Itu meningkat dengan cepat
Wayne Werner

18
Jika ada orang lain yang bertanya-tanya mengapa ini dikompilasi: stackoverflow.com/questions/34764796/…
TC

206

C #, sekitar 1 menit untuk dikompilasi, biner keluaran 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;}}

Menambahkan lebih banyak Y akan meningkatkan ukuran secara eksponensial.

Penjelasan oleh Pharap sesuai permintaan @Odomontois:

Jawaban ini menyalahgunakan pewarisan dan ketik parameter untuk membuat rekursi. Untuk memahami apa yang terjadi, lebih mudah untuk menyederhanakan masalah terlebih dahulu. Pertimbangkan class X<A> { class Y : X<Y> { Y y; } }, yang menghasilkan kelas generik X<A>, yang memiliki kelas dalam Y. X<A>.Ymewarisi X<Y>, karenanya X<A>.Yjuga memiliki kelas batin Y, yang kemudian X<A>.Y.Y. Ini kemudian juga memiliki kelas dalam Y, dan bahwa kelas dalam Ymemiliki kelas dalam Ydll. Ini berarti bahwa Anda dapat menggunakan resolusi lingkup ( .) tanpa batas, dan setiap kali Anda menggunakannya, kompiler harus menyimpulkan tingkat pewarisan dan jenis parameterisasi lainnya .

Dengan menambahkan parameter tipe tambahan, pekerjaan yang harus dilakukan oleh kompiler pada setiap tahap semakin meningkat.

Pertimbangkan kasus-kasus berikut:
Dalam class X<A> { class Y : X<Y> { Y y;} }tipe param Amemiliki tipe X<A>.Y.
Dalam class X<A> { class Y : X<Y> { Y.Y y;} }tipe param Amemiliki tipe X<X<A>.Y>.Y.
Dalam class X<A> { class Y : X<Y> { Y.Y.Y y;} }tipe param Amemiliki tipe X<X<X<A>.Y>.Y>.Y.
Dalam class X<A,B> { class Y : X<Y,Y> { Y y;} }jenis param Aadalah X<A,B>.Ydan Badalah X<A,B>.Y.
Dalam class X<A> { class Y : X<Y> { Y.Y y;} }jenis param Aadalah X<X<A,B>.Y, X<A,B>.Y>.Ydan Badalah X<X<A,B>.Y, X<A,B>.Y>.Y.
Dalam class X<A> { class Y : X<Y> { Y.Y.Y y;} }jenis param Aadalah X<X<X<A,B>.Y, X<A,B>.Y>.Y, X<X<A,B>.Y, X<A,B>.Y>.Y>.Ydan Badalah X<X<X<A,B>.Y, X<A,B>.Y>.Y, X<X<A,B>.Y, X<A,B>.Y>.Y>.Y.

Mengikuti pola ini, satu hanya dapat membayangkan 1 pekerjaan compiler harus lakukan untuk menyimpulkan apa Ayang Eberada di Y.Y.Y.Y.Y.Y.Y.Y.Ydalam definisi 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 Anda bisa mengetahuinya, tetapi Anda perlu banyak kesabaran, dan kecerdasan tidak akan membantu Anda di sini.


14
Ini lebih seperti jenis kegilaan yang kuharapkan! Sepertinya saya akan menginstal ulang Mono ...
Dave

31
Bisakah Anda memberikan penjelasan tentang efek yang begitu terkenal?
Odomontois

16
+1 untuk melakukan lebih dari sekadar menginisialisasi array besar.
Stig Hemmer

6
Berikut ini contoh menggunakan Try Roslyn dan hanya 3 Ydetik .
Kobi

10
Saya melihat pertanyaan ini dan segera memikirkan Anda. Bagus!
Eric Lippert

154

Python 3, sumber 13 byte, 9.057.900.463 byte (8,5GiB) .pyc-file

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

Sunting : Mengubah kode ke versi di atas setelah saya menyadari aturan mengatakan ukuran output di luar 4GiB tidak masalah, dan kode untuk yang ini sedikit lebih pendek; Kode sebelumnya - dan yang lebih penting penjelasannya - dapat ditemukan di bawah.


Python 3, 16 byte source,> 32TB .pyc-file (jika Anda memiliki cukup memori, ruang disk, dan kesabaran)

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

Penjelasan: Python 3 melakukan pelipatan konstan, dan Anda mendapatkan angka besar cepat dengan eksponen. Format yang digunakan oleh file .pyc menyimpan panjang representasi integer menggunakan 4 byte, dan pada kenyataannya batas tampaknya lebih seperti 2**31, jadi hanya dengan menggunakan eksponen untuk menghasilkan satu angka besar, batas tersebut tampaknya menghasilkan 2GB. file pyc dari sumber 8 byte. ( 19**8Sedikit malu 8*2**31, jadi1<<19**8 memiliki representasi biner tepat di bawah 2GB; perkalian dengan delapan adalah karena kita ingin byte, bukan bit)

Namun, tuple juga tidak dapat diubah dan mengalikan tuple juga konstan dilipat, sehingga kita dapat menduplikasi gumpalan 2GB itu sebanyak yang kita inginkan 2**31, mungkin setidaknya sampai beberapa kali. Untuk 4**7sampai ke 32TB dipilih hanya karena itu adalah eksponen pertama yang saya temukan yang mengalahkan jawaban 16TB sebelumnya.

Sayangnya, dengan memori yang saya miliki di komputer saya sendiri, saya bisa menguji ini hanya hingga 2 pengganda, yaitu. (1<<19**8,)*2, yang menghasilkan file 8.5GB, yang saya harap menunjukkan bahwa jawabannya realistis (mis. ukuran file tidak terbatas pada 2 ** 32 = 4GB).

Juga, saya tidak tahu mengapa ukuran file yang saya dapatkan saat pengujian adalah 8.5GB, bukan 4GB-ish yang saya harapkan, dan file tersebut cukup besar sehingga saya tidak merasa ingin menyentuhnya saat ini.


2
+1, tapi mengapa tidak (1<<19**8,)*2? 4GB sudah cukup.
Akangka

2
@ChristianIrwan: Ya, saya lupa aturan itu, baru menyadarinya beberapa menit yang lalu dan belum menemukan jenis pengeditan yang harus saya buat. :-)
Aleksi Torhamo

1
Bagus. Karena ini hanya 13 byte, kami akhirnya memiliki penantang jawaban pertama yang diposting! Saya hanya dapat mengkonfirmasi 1<<18pada mesin saya (1.5GB) tetapi saya akan mengujinya di linux nanti, di mana saya berharap itu akan bekerja dengan 8GB penuh (tidak akan mencoba versi 32TB!)
Dave

1
@ Dave: Ukuran pastinya mungkin tergantung pada versinya (1.5GB terdengar aneh bagaimanapun juga); Saya menggunakan Python 3.3.5, dan digunakan python -m py_compile asd.pyuntuk menghasilkan file .pyc.
Aleksi Torhamo

3
IIRC, python menggunakan 30 bit per 32-bit kata dalam representasi

130

Jika output lebih dari 4GB tercapai (mungkin jika seseorang menemukan preprocessor lengkap turing), kompetisi akan menjadi sumber terkecil yang menghasilkan file sekurang-kurangnya sebesar itu (tidak praktis untuk menguji pengiriman yang terlalu besar) .

"Templat Haskell" memungkinkan kode Haskell dihasilkan pada waktu kompilasi menggunakan Haskell, dan karenanya merupakan pre-processor yang lengkap.

Inilah upaya saya, yang diparameterisasi oleh ekspresi numerik yang berubah-ubah FOO:

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

Keajaiban adalah kode di dalam "sambatan" $(...). Ini akan dieksekusi pada waktu kompilasi, untuk menghasilkan AST Haskell, yang dicangkokkan ke AST program sebagai ganti sambungan.

Dalam hal ini, kami membuat AST sederhana yang mewakili literal 0, kami mereplikasi FOOkali ini untuk membuat daftar, lalu kami gunakan ListEdari Language.Haskell.THmodul untuk mengubah daftar AST ini menjadi satu AST besar, mewakili literal [0, 0, 0, 0, 0, ...].

Program yang dihasilkan setara main = print [0, 0, 0, ...]dengan FOOpengulangan dari 0.

Untuk mengkompilasi ke 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

Ini berbobot pada 83 byte (66 untuk kode Haskell dan 17 untuk -XTemplateHaskellargumen), ditambah panjang FOO.

Kita dapat menghindari argumen kompiler dan hanya mengompilasinya ghc, tetapi kita harus meletakkannya {-# LANGUAGE TemplateHaskell#-}di awal, yang menabrak kode hingga 97 byte.

Berikut adalah beberapa contoh ekspresi untuk FOO, dan ukuran biner yang dihasilkan:

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

Saya kehabisan kompilasi dengan RAM (2^20).

Kami juga dapat membuat daftar tanpa batas, menggunakan repeatbukan replicate FOO, tetapi itu mencegah kompiler berhenti;)


46
Selamat datang di Programming Puzzles and Code Golf. Ini adalah jawaban yang brilian , terutama bagi pengguna baru ke situs ini. Jika Anda membutuhkan bantuan (yang saya ragu), jangan ragu untuk bertanya.
wizzwizz4

3
@ wizzwizz4: Ya, itu adalah jawaban yang brilian. Ini pada dasarnya sama dengan milik saya, kecuali bahwa di Haskell itu memerlukan arahan kompiler khusus untuk membuat metaprogramming bekerja. ;)
Mason Wheeler

2
Ketika saya mengkompilasi dengan GHC 7.8.3 saya mendapatkan "Tidak dalam lingkup: '<$>'" (Saya mengatur kode ke [...].replicate (2^10)<$>[|0|])). Saya tidak berpengalaman dengan Haskell; ada petunjuk tentang cara membuat kompilasi ini?
Dave

38
Sayang sekali template haskell tidak cukup malas untuk mengalirkan executable tanpa batas.
PyRulez

1
Hai @Dave <$>fungsi ini banyak digunakan di Haskell, tetapi hanya dipindahkan ke "prelude" (sekumpulan fungsi yang tersedia secara default) di GHC 7.10. Untuk versi sebelumnya, Anda harus menambahkan import Control.Applicative;setelah importpernyataan yang ada. Saya baru saja mencoba dengan GHC 7.8.4 dan berhasil.
Warbo

80

C ++, 250 + 26 = 276 byte

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;

Ini adalah fungsi Ackermann yang diimplementasikan dalam template. Saya tidak dapat mengkompilasi dengan h=a<4,2>::n;mesin kecil (6GB) saya, tetapi saya berhasil h=a<3,14>untuk file output 26M. Anda dapat menyetel konstanta untuk mencapai batas platform Anda - lihat artikel Wikipedia yang tertaut untuk panduan.

Membutuhkan -g flag ke GCC (karena itu semua simbol debug yang benar-benar mengkonsumsi ruang apa saja), dan kedalaman templat yang lebih besar dari standar. Baris kompilasi saya berakhir sebagai

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

Informasi platform

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

Saya sangat suka yang ini, tapi saya tidak yakin saya bisa menerima output .o, karena saya memang mengatakan ELF / .exe / etc. (dan kompilasi ini sepenuhnya mengoptimalkan semuanya!). Tetap saja, +1 (dan dikonfirmasi)
Dave

4
Pembaruan: Seperti yang ditunjukkan Ben Voigt pada jawabannya, GCC di Linux memang menghasilkan file ELF sebagai output .o, dan saya sudah bisa mengonfirmasi varian <3,14> dengannya, jadi ya - ini valid.
Dave

17
Saya mengharapkan sesuatu yang aneh untuk keluar dari template C ++. Saya tidak mengharapkan fungsi Ackermann.
Markus

tidak akankah Fibonacci memberi Anda kode yang lebih kecil dan kontrol ukuran keluaran yang lebih baik?
Will Ness

1
Tapi kami ingin kode yang lebih besar! Fibonacci memberikan ukuran yang hampir sama dengan kode linear murni (tetapi waktu kompilasi lebih lama dari linear). Anda pasti bisa bersenang-senang dengan berbagai ukuran statis A+Bdi setiap kelas, sekarang saya memikirkannya ...
Toby Speight

65

ASM, 61 byte (sumber 29 byte, flag 32 byte), 4.294.975.320 byte dapat dieksekusi

.globl main
main:
.zero 1<<32

Kompilasi dengan gcc the_file.s -mcmodel=large -Wl,-fuse-ld=gold


5
1<<30cukup baik untuk C. Karena ini adalah assembler, ukurannya adalah dalam byte.
viraptor

2
@ Viraptor Sistem saya memiliki 32GB RAM dan untuk iseng saya mencoba membangun kode Anda. asberhasil menyerahkan ld, tetapi ldgagal dengan ini . Bahkan -mcmodel=mediumsepertinya tidak membantu.
Iwillnotexist Idonotexist

2
coba paksakan penggunaan tautan gold: gcc -fuse-ld=gold ...kompilasi / tautan ... eek! Selesai dalam 1:29 (89 detik) dan ukuran 1.073.748.000 byte.
lornix

2
Saya akhirnya mendapatkan ini untuk berkumpul di Ubuntu 15.10 64-bit, dengan doa gcc -o g g.s -mcmodel=large -Wl,-fuse-ld=gold. Penghitungan akhir:, 4,294,975,320 bytesdengan 32 byte tambahan ditambahkan ke panjang program untuk -mcmodel=large -Wl,-fuse-ld=gold. Perlu dicatat bahwa tajuknya salah; sumbernya adalah 29 byte (tanpa bendera tambahan ditambahkan).
Mego

3
Dengan meningkatkan alokasi hingga 1<<33, saya berakhir dengan 8,589,942,616byte yang dapat dieksekusi.
Mego

60

Inilah jawaban C saya dari tahun 2005. Akan menghasilkan biner 16TB jika Anda memiliki RAM 16TB (Anda tidak).

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
"Akan menghasilkan biner 16TB jika Anda memiliki RAM 16TB (Anda tidak)." - saya juga tidak memiliki hard drive 16TB! Saya tidak bisa benar-benar memverifikasi ini, tapi tetap saja keren.
Dave

5
Saya menemukan ini secara tidak sengaja dan menyaksikan kompiler roboh ketika kehabisan ruang alamat.
Joshua

8
Tolong, JANGAN mencoba membuat golf entri ini; golf mengalahkan maksud sampel kode dan toh tidak ada manfaat skor untuk melakukannya. Kode sudah GPL sejak 2005.
Joshua

6
@BenVoigt Apapun, mengedit kode orang lain tidak pernah diterima di sini. Tinggalkan komentar jika ada masalah. Pos meta yang relevan: meta.codegolf.stackexchange.com/questions/1615/…
Mego

2
@ Yosua: Periksa perbedaan markdown. Mego hanya menambahkan petunjuk yang disorot.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

25

Preprosesor C biasa: input 214 byte, output 5MB

Terinspirasi oleh preprosesor dunia nyata saya gagal di sini .

#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; }

Eksperimen menunjukkan bahwa setiap tingkat #definekehendak (seperti yang diharapkan) membuat output sekitar sepuluh kali lebih besar. Tetapi karena contoh ini membutuhkan waktu lebih dari satu jam untuk dikompilasi, saya tidak pernah melanjutkan ke "G".


9
Ini agak seperti bom xml
earwig

9
Secara khusus ini merupakan implementasi dari "Billion Laughs" asli.
mınxomaτ

Ini gila namun sederhana.
Vahid Amiri

2
Wow, ini sebenarnya menyebabkan segfault di GCC 4.9 dan Dentang. Kompiler mana yang Anda gunakan?
Dave

1
@Dave: Aneh. Ketika saya mengkompilasi menggunakan make, ia mengkompilasi, tetapi jika saya mengetikkan perintah yang sama persis yang membuat menggunakan, itu crash. Dan itu tampaknya tidak terkait dengan variabel lingkungan.
Thomas Padron-McCarthy

24

Java, 450 + 22 = 472 sumber byte, ~ file kelas 1GB

B.java (versi golf, peringatan saat kompilasi)

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.java (versi 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;
    }
}

Kompilasi

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

Penjelasan

Bom ini menggunakan Prosesor Anotasi. Perlu 2 kompilasi pass. Lulus pertama membangun kelas prosesor B. Selama pass kedua prosesor membuat file sumber baru C.java, dan mengkompilasinya ke C.classdengan ukuran 1,073,141,162byte.

Ada beberapa batasan saat mencoba membuat file kelas besar:

  • Menciptakan pengidentifikasi lebih dari sekitar 64k hasil dalam: error: UTF8 representation for string "iiiiiiiiiiiiiiiiiiii..." is too long for the constant pool.
  • Membuat lebih dari sekitar 64 ribu variabel / fungsi menghasilkan: error: too many constants
  • Ada juga batas sekitar 64rb untuk ukuran kode suatu fungsi.
  • Tampaknya ada batas umum (bug?) Di kompiler java sekitar 1GB untuk .classfile tersebut. Jika saya meningkat 16380menjadi16390 dalam kode di atas compiler tidak pernah kembali.
  • Ada juga batas sekitar 1GB untuk .javafile tersebut. Peningkatan 16380ke 16400dalam kode di atas menghasilkan: An exception has occurred in the compiler (1.8.0_66). Please file a bug ...diikuti oleh a java.lang.IllegalArgumentException.

10
Rapi; Anda pada dasarnya membuat preprocessor Anda sendiri, dalam batas ukuran, dalam bahasa dengan kompiler yang secara native mendukung preprosesor khusus. Itu dalam aturan. Kelas terakhir hanya 0,5GB untuk saya, tetapi saya dapat mengkonfirmasi metode ini.
Dave

Contoh lain di Java habrahabr.ru/post/245333 - ia menggunakan bersarang try..finally(kode pada akhirnya blok diduplikasi untuk kasus normal dan luar biasa) dan blok initializer (kode dari blok initializer ditambahkan ke setiap konstruktor)
Victor

Saya mengganti ädengan idan menyesuaikan angka. Sekarang bom harus membuat kelas 1GB pada sistem apa pun tanpa masalah penyandian. Namun, sekarang membutuhkan lebih banyak memori.
Sleafar

? memperpanjang TypeElement?!?
kucing


22

C, sumber 26 byte, 2.139.103.367 keluaran, program yang valid

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

Dikompilasi menggunakan: gcc cbomb.c -o cbomb(gcc versi 4.6.3, Ubuntu 12.04, ~ 77 detik)

Saya pikir saya akan mencoba melihat seberapa besar saya bisa membuat program yang valid tanpa menggunakan opsi baris perintah apa pun. Saya mendapat ide dari jawaban ini: https://codegolf.stackexchange.com/a/69193/44946 oleh Digital Trauma. Lihat komentar di sana mengapa ini mengkompilasi.

Cara kerjanya: constMenghapus bendera tulis dari halaman di segmen, sehingga utama dapat dijalankan. Itu195 adalah kode mesin Intel untuk pengembalian. Dan karena arsitektur Intel adalah little-endian, ini adalah byte pertama. Program akan keluar dengan apa pun kode start up yang dimasukkan ke dalam register eax, kemungkinan 0.

Ini hanya sekitar 2 pertunjukan karena linker menggunakan nilai yang ditandatangani 32 bit untuk offset. Ini 8 mc lebih kecil dari 2 manggung karena kompiler / penghubung memerlukan beberapa ruang untuk bekerja dan ini adalah yang terbesar yang bisa saya dapatkan tanpa kesalahan penghubung - ymmv.


3
Sebagai tambahan yang menarik, outputnya adalah 2.078.451 byte gziped dengan kompresi maksimum = 1029: 1 rasio kompresi.
Zakipu

20

Boo , 71 byte. Waktu kompilasi: 9 menit. Dapat dieksekusi 134.222.236 byte

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

Menggunakan makro R(untuk Ulangi) untuk menyebabkan kompiler mengalikan pernyataan kenaikan beberapa kali secara acak. Tidak diperlukan flag compiler khusus; cukup simpan file sebagai bomb.boodan aktifkan kompiler dengan booc bomb.boountuk membangunnya.


2**e-apa ini? Coba 9**e!
wchargin

1
@WChargin: Hal yang menyenangkan tentang metaprogramming adalah betapa mudahnya Anda dapat menyesuaikannya!
Mason Wheeler

Saya mengalami sedikit masalah dalam menginstal boo ... Saya akan mengkonfirmasi yang ini ketika saya berhasil menginstalnya!
Dave

@Dave Masalah apa yang Anda alami dengan itu?
Mason Wheeler

16

Kotlin , sumber 90 byte, 177416 byte (173 KB) disusun biner 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)}}}}}}}}}}}

Secara teknis, Anda bisa membuatnya lebih lama dengan menyarangkan ekspresi lebih jauh. Namun, kompiler macet dengan StackOverflowkesalahan jika Anda meningkatkan rekursi.


Awalan SI Anda tidak setuju. Apakah itu 177416 kilobyte = 173 MB, atau 177416 byte = 173 kB?
Ben Voigt

1
@BenVoigt Terima kasih telah menunjukkan: D
TheNumberOne

Mengesankan, dapatkan +1
J Atkin

Untuk mengkompilasi Kotlin 1.2.20 kita perlu menghapus satu kedalaman dan ~ 104kB. Versi mana yang Anda gunakan awalnya?
TWiStErRob

15

C ++, 214 byte (tidak diperlukan opsi kompilasi khusus)

#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();

Ini adalah rekursi template dua dimensi yang cukup mudah (kedalaman rekursi berjalan sebagai akar kuadrat dari total template yang dipancarkan, sehingga tidak akan melebihi batas platform), dengan sejumlah kecil data statis di masing-masingnya.

File objek yang dihasilkan dengan g++ 4.9.3 x86_64-pc-cygwinadalah 2567355421 byte (2.4GiB).

Meningkatkan nilai awal di atas 80 akan merusak assembler cygwin gcc (terlalu banyak segmen).

Juga, 99999dapat diganti dengan 9<<19atau serupa untuk memperbesar ukuran tanpa mengubah kode sumber ... tapi saya tidak berpikir saya perlu menggunakan lebih banyak ruang disk daripada yang sudah saya lakukan;)


Dikonfirmasi (pada kenyataannya, ini 2.56GB dengan dentang), tetapi perlu -cflag kompilasi untuk menghentikan linker (2 byte tambahan), dan saya tidak yakin saya dapat menerima output .o (bukan salah satu yang saya daftarkan). Tetap saja, saya menyukainya, jadi +1.
Dave

@Dave: file gcc .o adalah format ELF bukan?
Ben Voigt

Tidak yakin. Mereka tidak memulai dengan angka ajaib ELF ketika saya menghasilkan mereka ... Saya akan menyelidiki nanti.
Dave

@ Dave: Ya, cygwin gcc tidak menghasilkan file ELF. Linux gcc tampaknya (walaupun saya sedang melihat satu dari bagian kode yang berbeda)
Ben Voigt

Ya, GCC 5.2.1 di Kubuntu memang menghasilkan file ELF, tetapi hanya 9MB! Tidak yakin bagaimana ia berhasil mengompresnya jauh dibandingkan dengan kompiler lain. Mungkin GCC 4.9 akan membuat file ELF 2GB.
Dave

6

Scala - sumber 70 byte, hasil 22980842 byte (setelah tabung)

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

Ini menghasilkan 9 5 (sekitar 59.000) file kelas khusus, yang dikemas ke dalam toples sekitar 23 MB. Pada prinsipnya Anda dapat terus berjalan jika Anda memiliki sistem file yang dapat menangani banyak file dan cukup memori.

(Jika perintah jar harus dimasukkan, itu 82 byte.)


Aku tidak bisa compile: error: java.lang.OutOfMemoryError: GC overhead limit exceeded. Bisakah Anda juga mendokumentasikan perintah yang diperlukan untuk kompilasi?
P.Péter

@ P.Péter - Anda perlu memberi kompiler lebih banyak memori, mis. scalac -J-Xmx12G X.scalaAdalah apa yang saya gunakan. Saya tidak menguji berapa yang sebenarnya dibutuhkan.
Rex Kerr

masih belum mengkompilasi, sayangnya :( 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 foundBisakah Anda menentukan versi scala dan java (mungkin platform juga)? Saya menggunakan scalac 2.9.2 dan OpenJDK 1.8.0_66-internal-b17, pada debian 8 x86-64.
P.Péter

Ubuntu 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
Rex Kerr

2

C, 284 byte + 2 untuk -cin gcc bomb.c -o bomb.o -c; output: 2 147 484 052 byte

#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

Boo, jauh lebih dari yang Anda harapkan dari ini

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

Ini terlihat seperti jawaban Mason Wheeler dengan beberapa perubahan kecil (??). Apakah Anda mencapai jawaban yang sama secara mandiri atau ada sesuatu yang penting dalam nilai yang Anda ubah (jika demikian, harap edit jawaban untuk menjelaskan mengapa itu penting).
Dave

0

Python 3:

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

Bom tetrasi


2
Anda harus menunjukkan berapa banyak byte output, untuk melihat bagaimana entri Anda dibandingkan dengan yang lain.
Sanchises

Selamat datang di PPCG! Sepertinya Anda tidak sengaja membuat dua akun dan memposting jawaban ini dua kali. Saya telah menghapus jawaban lainnya. Seperti dikatakan Sanchises, tantangan ini dinilai dengan ukuran program yang disusun . Jadi, Anda harus memasukkan ukuran itu dalam jawaban Anda karena itu adalah skor utama. Perhatikan juga bahwa program yang sebenarnya tidak akan terlalu besar, hanya ekspresi yang Anda buat di memori, jadi Anda mungkin ingin memikirkan pendekatan yang berbeda.
Martin Ender

1
@ MartinEnder karena bagaimana Python mengevaluasi beberapa ekspresi pada waktu kompilasi dan menyimpan angka dalam presisi arbitrer, ini akan (dalam teori) memiliki eksekusi yang agak besar. Tetapi seperti yang dicatat oleh Aleksi Torhamo (yang menggunakan teknik yang sama untuk sebagian dari jawabannya), ini memiliki batas sekitar 2GB, jadi saya berharap kode ini ditulis mungkin tidak akan dikompilasi (walaupun saya belum memeriksa ). Jika OP dapat membuatnya untuk mengkompilasi dan memposting ukuran yang dikompilasi (bersama dengan perintah yang diperlukan untuk membuatnya), maka itu valid. Kemiripan dengan jawaban Aleksi yang sudah ada terlihat seperti kebetulan bagi saya.
Dave
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.