Xây dựng một quả bom biên dịch


372

Giới thiệu

Có lẽ bạn đã quen thuộc với bom zip , bom XML , v.v. Nói một cách đơn giản, chúng là những tệp nhỏ (tương đối) tạo ra sản lượng khổng lồ khi được giải thích bởi phần mềm ngây thơ. Thách thức ở đây là lạm dụng một trình biên dịch theo cùng một cách.

Thử thách

Viết một số mã nguồn chiếm 512 byte trở xuống và biên dịch thành một tệp chiếm dung lượng lớn nhất có thể. Tập tin đầu ra lớn nhất sẽ thắng!

Quy tắc

OK, vì vậy có một vài làm rõ, định nghĩa và hạn chế quan trọng;

  • Đầu ra của quá trình biên dịch phải là tệp ELF , Windows Portable Executable (.exe) hoặc mã byte ảo cho JVM hoặc .Net's CLR (các loại mã byte ảo khác cũng có thể ổn nếu được yêu cầu). Cập nhật: Sản lượng .pyc / .pyo của Python cũng được tính .
  • Nếu ngôn ngữ lựa chọn của bạn không thể được biên dịch trực tiếp thành một trong những định dạng đó, thì việc dịch mã theo sau là biên dịch cũng được cho phép ( Cập nhật: bạn có thể dịch mã nhiều lần, miễn là bạn không bao giờ sử dụng cùng một ngôn ngữ nhiều lần ).
  • Mã nguồn của bạn có thể bao gồm nhiều tệp và thậm chí cả tệp tài nguyên, nhưng kích thước tổng của tất cả các tệp này không được vượt quá 512 byte.
  • Bạn không thể sử dụng bất kỳ đầu vào nào khác ngoài (các) tệp nguồn và thư viện chuẩn của ngôn ngữ bạn chọn. Thư viện tiêu chuẩn liên kết tĩnh là OK khi được hỗ trợ. Cụ thể, không có thư viện bên thứ ba hoặc thư viện hệ điều hành.
  • Nó phải có khả năng gọi trình biên dịch của bạn bằng cách sử dụng một lệnh hoặc một loạt các lệnh. Nếu bạn yêu cầu các cờ cụ thể khi biên dịch, các số này sẽ được tính vào giới hạn byte của bạn (ví dụ: nếu dòng biên dịch của bạn là gcc bomb.c -o bomb -O3 -lm, -O3 -lmphần (7 byte) sẽ được tính (lưu ý không gian hàng đầu ban đầu không được tính).
  • Tiền xử lý chỉ được phép nếu chúng là một tùy chọn biên dịch chuẩn cho ngôn ngữ của bạn.
  • Môi trường tùy thuộc vào bạn, nhưng vì lợi ích của việc xác minh điều này, vui lòng tuân theo các phiên bản trình biên dịch và hệ điều hành gần đây (có sẵn) (và rõ ràng chỉ định bạn đang sử dụng).
  • Nó phải biên dịch mà không có lỗi (cảnh báo là OK) và sự cố trình biên dịch không được tính cho bất cứ điều gì.
  • Những gì chương trình của bạn thực sự làm là không liên quan, mặc dù nó không thể là bất cứ điều gì độc hại. Nó thậm chí không phải bắt đầu.

ví dụ 1

Chương trình C

main(){return 1;}

Được biên dịch Apple LLVM version 7.0.2 (clang-700.1.81)trên OS X 10.11 (64-bit):

clang bomb.c -o bomb -pg

Tạo một tệp 9228 byte. Tổng kích thước nguồn là 17 + 3 (đối với -pg) = 20 byte, dễ dàng trong giới hạn kích thước.

Ví dụ 2

Chương trình Brainfuck:

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

Được dịch với awib đến c với:

./awib < bomb.bf > bomb.c

Sau đó được biên dịch với Apple LLVM version 7.0.2 (clang-700.1.81)trên OS X 10.11 (64-bit):

clang bomb.c

Tạo một tệp 8464 byte. Tổng đầu vào ở đây là 143 byte (vì đây @lang_clà mặc định cho awib nên không cần thêm vào tệp nguồn và không có cờ đặc biệt nào trong cả hai lệnh).

Cũng lưu ý rằng trong trường hợp này, tệp bomb.c tạm thời là 802 byte, nhưng điều này không tính đến kích thước nguồn cũng như kích thước đầu ra.

Lưu ý cuối cùng

Nếu đạt được sản lượng hơn 4GB (có lẽ nếu ai đó tìm thấy bộ tiền xử lý hoàn chỉnh), thì sự cạnh tranh sẽ dành cho nguồn nhỏ nhất tạo ra một tệp có kích thước tối thiểu (không thực tế để kiểm tra các bài nộp quá lớn) .


Nếu sử dụng bộ chuyển mã, mã nguồn đầu ra có cần dưới 512 byte cũng như mã nguồn đầu vào không?
trichoplax

3
Được phép lặp lại transpilation?
orlp

3
@ LegionMammal978 có, nó phải tạo một trong các loại tệp tôi đã chỉ định. Nhưng nếu bạn nghĩ rằng bạn đã tìm thấy thứ gì đó giống máy ảo hơn ngôn ngữ được giải thích, hãy hỏi về nó một cách cụ thể và tôi có thể cho phép nó (nó hơi chủ quan nên tôi muốn bắt đầu rất hạn chế, với tùy chọn về việc mở nó lên)
Dave

3
@trichoplax Tôi không biết điều đó, nhưng từ một số người đọc có vẻ như có; biên dịch sang Python bytecode hoàn toàn được tính. Vì vậy, đối với python, kích thước đầu ra sẽ là tổng kích thước của tất cả các tệp pyc / pyo của bạn. Tôi sẽ cập nhật câu hỏi sớm với các cập nhật dựa trên nhận xét này.
Dave

2
@MartinRosenau - WGroleau đã hỏi một câu hỏi tương tự; đó là tiêu chuẩn trong các thử thách mã hóa mà bạn có thể sử dụng bất cứ thứ gì đã tồn tại khi thử thách bắt đầu.
Dave

Câu trả lời:


441

C, (14 + 15) = 29 byte nguồn, 17.179.875.837 (16 GB) byte thực thi

Cảm ơn @viraptor đã tắt 6 byte.

Cảm ơn @hvd đã tắt 2 byte và kích thước thực thi x4.

Điều này định nghĩa mainhàm là một mảng lớn và khởi tạo phần tử đầu tiên của nó. Điều này khiến GCC lưu trữ toàn bộ mảng trong kết quả thực thi.

Vì mảng này lớn hơn 2GB, chúng tôi cần cung cấp -mcmodel=mediumcờ cho GCC. Thêm 15 byte được bao gồm trong điểm, theo quy tắc.

main[-1u]={1};

Đừng mong đợi mã này sẽ làm bất cứ điều gì tốt đẹp khi chạy.

Biên dịch với:

gcc -mcmodel=medium cbomb.c -o cbomb

Phải mất một thời gian để tôi có thể thử nghiệm đề xuất của @ hvd - và tìm một máy có đủ nước để xử lý nó. Cuối cùng, tôi tìm thấy một máy ảo RedHat 5.6 không sản xuất cũ với RAM 10 GB, trao đổi 12 GB và / tmp được đặt thành một phân vùng cục bộ lớn. Phiên bản GCC là 4.1.2. Tổng thời gian biên dịch khoảng 27 phút.

Do tải CPU và RAM, tôi khuyên bạn không nên thực hiện việc biên dịch này trên bất kỳ máy nào liên quan đến sản xuất từ ​​xa .



13
Tôi đang chơi với giải pháp của tôi ở đây, nhưng ... bạn không cần a. Bạn chỉ có thể sử dụngmain[1<<30]={1};
viraptor

38
Ôi trời. Điều này là xấu xa. X đóng băng trong vài phút cố gắng biên dịch mã đó. Tôi đã bắt đầu tìm kiếm một máy tính khác để có thể quay lại và giết tiến trình gcc trước khi nó hoạt động trở lại. Btw. Nếu bạn muốn một giá trị lớn hơn 1<<30thì 7<<28có thể là một lựa chọn.
kasperd

33
> 4gb? Điều đó đã leo thang nhanh chóng
Wayne Werner

18
Trong trường hợp bất cứ ai khác đang tự hỏi tại sao điều này biên dịch: stackoverflow.com/questions/34764796/NH
TC

206

C #, khoảng 1 phút để biên dịch, nhị phân đầu ra 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;}}

Thêm nhiều chữ Y sẽ tăng kích thước theo cấp số nhân.

Giải thích của Pharap theo yêu cầu của @Odomontois:

Câu trả lời này là lạm dụng các tham số thừa kế và loại để tạo đệ quy. Để hiểu những gì đang xảy ra, trước tiên, đơn giản hóa vấn đề. Hãy xem xét class X<A> { class Y : X<Y> { Y y; } }, tạo ra lớp chung X<A>, trong đó có một lớp bên trong Y. X<A>.Ykế thừa X<Y>, do đó X<A>.Ycũng có một lớp bên trong Y, đó là sau đó X<A>.Y.Y. Điều này sau đó cũng có một lớp bên trong Yvà lớp bên trong đó Ycó một lớp bên trong, Yv.v. Điều này có nghĩa là bạn có thể sử dụng .ad infinitum và độ phân giải phạm vi , và mỗi khi bạn sử dụng nó, trình biên dịch phải suy ra một mức độ khác của tham số và kiểu tham số .

Bằng cách thêm các tham số loại bổ sung, công việc mà trình biên dịch phải thực hiện ở mỗi giai đoạn được tăng thêm.

Xem xét các trường hợp sau:
Trong class X<A> { class Y : X<Y> { Y y;} }loại param Acó một loại X<A>.Y.
Trong class X<A> { class Y : X<Y> { Y.Y y;} }loại param Acó một loại X<X<A>.Y>.Y.
Trong class X<A> { class Y : X<Y> { Y.Y.Y y;} }loại param Acó một loại X<X<X<A>.Y>.Y>.Y.
Trong class X<A,B> { class Y : X<Y,Y> { Y y;} }loại param AX<A,B>.YBX<A,B>.Y.
Trong class X<A> { class Y : X<Y> { Y.Y y;} }loại param AX<X<A,B>.Y, X<A,B>.Y>.YBX<X<A,B>.Y, X<A,B>.Y>.Y.
Trong class X<A> { class Y : X<Y> { Y.Y.Y y;} }loại param AX<X<X<A,B>.Y, X<A,B>.Y>.Y, X<X<A,B>.Y, X<A,B>.Y>.Y>.YBX<X<X<A,B>.Y, X<A,B>.Y>.Y, X<X<A,B>.Y, X<A,B>.Y>.Y>.Y.

Sau mô hình này, người duy nhất có thể tưởng tượng 1 công việc trình biên dịch sẽ phải làm gì để suy ra những gì Ađể Eđược ở Y.Y.Y.Y.Y.Y.Y.Y.Ytrong định nghĩa 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 Bạn có thể tìm ra điều đó, nhưng bạn cần rất nhiều kiên nhẫn, và intellisense sẽ không giúp bạn ra khỏi đây.


14
Điều này giống như kiểu điên rồ mà tôi đang mong đợi! Có vẻ như tôi đã tắt để cài đặt lại Mono
Dave

31
Bạn có thể cung cấp một lời giải thích về hiệu ứng khét tiếng như vậy?
Odomontois

16
+1 để làm nhiều hơn là chỉ khởi tạo một mảng lớn.
Stig Hemmer

6
Đây là một ví dụ sử dụng Thử Roslyn và chỉ 3 Ygiây .
Kobi

10
Tôi thấy câu hỏi này và ngay lập tức nghĩ về bạn. Đẹp!
Eric Lippert

154

Python 3, nguồn 13 byte, 9.057.900.463 byte (8,5GiB) .pyc-file

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

Chỉnh sửa : Đã thay đổi mã thành phiên bản ở trên sau khi tôi nhận ra quy tắc nói rằng kích thước đầu ra vượt quá 4GiB không thành vấn đề và mã cho mã này ngắn hơn một chút; Mã trước - và quan trọng hơn là lời giải thích - có thể được tìm thấy bên dưới.


Python 3, nguồn 16 byte,> 32TB .pyc-file (nếu bạn có đủ bộ nhớ, dung lượng đĩa và sự kiên nhẫn)

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

Giải thích: Python 3 không gấp, và bạn nhận được số lớn nhanh với số mũ. Tuy nhiên, định dạng được sử dụng bởi các tệp .pyc lưu trữ độ dài của biểu diễn số nguyên bằng 4 byte và trong thực tế, giới hạn có vẻ giống hơn 2**31, vì vậy chỉ cần sử dụng số mũ để tạo một số lớn, giới hạn dường như tạo ra 2GB. tập tin pyc từ một nguồn 8 byte. ( 19**8hơi ngại 8*2**31, vì vậy 1<<19**8có biểu diễn nhị phân chỉ dưới 2GB; phép nhân với tám là vì chúng tôi muốn byte chứ không phải bit)

Tuy nhiên, các bộ dữ liệu cũng không thay đổi và nhân một bộ dữ liệu cũng được gấp lại liên tục, vì vậy chúng tôi có thể nhân đôi số lượng 2GB đó bao nhiêu lần tùy ý, ít nhất là 2**31nhiều lần. Việc 4**7đạt tới 32TB được chọn chỉ vì đó là số mũ đầu tiên tôi có thể tìm thấy đánh bại câu trả lời 16TB trước đó.

Thật không may, với bộ nhớ tôi có trên máy tính của riêng mình, tôi có thể kiểm tra điều này chỉ với số nhân là 2, tức là. (1<<19**8,)*2, đã tạo ra một tệp 8,5 GB, mà tôi hy vọng chứng minh rằng câu trả lời là thực tế (nghĩa là kích thước tệp không giới hạn ở 2 ** 32 = 4GB).

Ngoài ra, tôi không biết tại sao kích thước tệp tôi nhận được khi kiểm tra là 8,5 GB thay vì 4GB như tôi mong đợi và tệp đủ lớn để tôi không cảm thấy muốn chọc vào nó vào lúc này.


2
+1, nhưng tại sao không (1<<19**8,)*2? 4GB là đủ.
Akangka

2
@ChristianIrwan: Vâng, tôi đã quên quy tắc đó, chỉ nhận ra nó vài phút trước và chưa tìm ra loại chỉnh sửa nào tôi nên thực hiện. :-)
Aleksi Torhamo

1
Đẹp. Vì đây chỉ là 13 byte, cuối cùng chúng tôi cũng có một người thách thức câu trả lời được đăng đầu tiên! Tôi chỉ có thể xác nhận 1<<18trên máy của mình (1,5 GB) nhưng tôi sẽ kiểm tra nó trên linux sau, nơi tôi hy vọng nó sẽ hoạt động với 8GB đầy đủ (sẽ không thử phiên bản 32TB!)
Dave

1
@Dave: Kích thước chính xác có thể phụ thuộc vào phiên bản (1,5 GB nghe có vẻ kỳ lạ dù thế nào đi chăng nữa); Tôi đã sử dụng Python 3.3.5 và được sử dụng python -m py_compile asd.pyđể tạo tệp .pyc.
Aleksi Torhamo

3
IIRC, python sử dụng 30 bit cho mỗi từ 32 bit trong biểu diễn số nguyên của nó

130

Nếu đạt được sản lượng hơn 4GB (có lẽ nếu ai đó tìm thấy bộ tiền xử lý hoàn chỉnh), thì sự cạnh tranh sẽ là nguồn nhỏ nhất tạo ra một tệp có kích thước tối thiểu (không thực tế để kiểm tra các bài nộp quá lớn) .

"Mẫu Haskell" cho phép mã Haskell được tạo tại thời điểm biên dịch bằng Haskell, và do đó là một bộ xử lý trước hoàn chỉnh.

Đây là nỗ lực của tôi, được tham số hóa bằng biểu thức số tùy ý FOO:

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

Phép thuật là mã bên trong "mối nối" $(...). Điều này sẽ được thực hiện tại thời điểm biên dịch, để tạo ra Haskell AST, được ghép vào AST của chương trình thay cho mối nối.

Trong trường hợp này, chúng tôi tạo một AST đơn giản đại diện cho nghĩa đen 0, chúng tôi sao chép FOOlần này để tạo một danh sách, sau đó chúng tôi sử dụng ListEtừ Language.Haskell.THmô-đun để biến danh sách AST này thành một AST lớn, đại diện cho nghĩa đen [0, 0, 0, 0, 0, ...].

Chương trình kết quả tương đương main = print [0, 0, 0, ...]với FOOsự lặp lại của 0.

Để biên dịch sang 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

Cái này nặng 83 byte (66 cho mã Haskell và 17 cho -XTemplateHaskellđối số), cộng với độ dài của FOO.

Chúng ta có thể tránh đối số trình biên dịch và chỉ biên dịch với ghc, nhưng chúng ta phải đặt {-# LANGUAGE TemplateHaskell#-}ở đầu, điều này làm cho mã lên tới 97 byte.

Dưới đây là một vài biểu thức ví dụ cho FOOvà kích thước của nhị phân kết quả:

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

Tôi đã hết RAM biên dịch với (2^20).

Chúng tôi cũng có thể tạo một danh sách vô hạn, sử dụng repeatthay vì replicate FOO, nhưng điều đó ngăn trình biên dịch tạm dừng;)


46
Chào mừng bạn đến với Câu đố lập trình và Code Golf. Đây là một câu trả lời tuyệt vời , đặc biệt đối với một người dùng mới vào trang web này. Nếu bạn cần bất kỳ sự giúp đỡ (mà tôi nghi ngờ), hãy hỏi.
wizzwizz4

3
@ wizzwizz4: Vâng, đó là một câu trả lời tuyệt vời. Về cơ bản nó giống như của tôi, ngoại trừ trong Haskell, nó yêu cầu một trình biên dịch đặc biệt để làm cho chương trình siêu lập trình hoạt động. ;)
Mason Wheeler

2
Khi tôi biên dịch với GHC 7.8.3, tôi nhận được "Không nằm trong phạm vi: '<$>'" (Tôi đặt mã thành [...].replicate (2^10)<$>[|0|])). Tôi không có kinh nghiệm với Haskell; bất kỳ gợi ý về làm thế nào để biên dịch này?
Dave

38
Mẫu quá xấu haskell không đủ lười biếng để phát ra một tệp thực thi vô hạn.
PyRulez

1
Xin chào @Dave <$>chức năng được sử dụng rộng rãi trong Haskell, nhưng chỉ được chuyển đến "khúc dạo đầu" (bộ chức năng có sẵn theo mặc định) trong GHC 7.10. Đối với các phiên bản trước, bạn sẽ cần thêm import Control.Applicative;sau khi importtuyên bố. Tôi vừa thử với GHC 7.8.4 và nó hoạt động.
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;

Đây là chức năng Ackermann được triển khai trong các mẫu. Tôi không thể biên dịch h=a<4,2>::n;trên máy nhỏ (6GB) của mình, nhưng tôi đã quản lý h=a<3,14>tệp đầu ra 26M. Bạn có thể điều chỉnh các hằng số để đạt giới hạn của nền tảng của mình - xem bài viết Wikipedia được liên kết để được hướng dẫn.

Yêu cầu -ggắn cờ với GCC (vì đó là tất cả các biểu tượng gỡ lỗi thực sự tiêu tốn bất kỳ khoảng trống nào) và độ sâu mẫu lớn hơn mặc định. Dòng biên dịch của tôi đã kết thúc như

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

Thông tin nền tảng

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

Tôi thực sự thích cái này, nhưng tôi không chắc mình có thể chấp nhận đầu ra .o, vì tôi đã nói ELF / .exe / vv. (và biên dịch này hoàn toàn tối ưu hóa tất cả!). Tuy nhiên, +1 (và được xác nhận)
Dave

4
Cập nhật: Như Ben Voigt chỉ ra câu trả lời của mình, GCC trên Linux sẽ tạo các tệp ELF dưới dạng đầu ra .o và tôi đã có thể xác nhận biến thể <3,14> với nó, vì vậy yup - điều này hợp lệ.
Dave

17
Tôi đã mong đợi một cái gì đó vô lý đến từ các mẫu C ++. Tôi đã không mong đợi chức năng Ackermann.
Đánh dấu

Fibre sẽ không cung cấp cho bạn mã nhỏ hơn và kiểm soát kích thước đầu ra tốt hơn?
Will Ness

1
Nhưng chúng tôi muốn mã lớn hơn! Fibonacci cho kích thước gần giống như mã tuyến tính thuần túy (nhưng thời gian biên dịch dài hơn tuyến tính). Bạn chắc chắn có thể vui vẻ với một mảng kích thước tĩnh A+Btrong mỗi lớp, bây giờ tôi nghĩ về nó ...
Toby Speight

65

ASM, 61 byte (nguồn 29 byte, 32 byte cho cờ), 4.294.975.320 byte thực thi

.globl main
main:
.zero 1<<32

Biên dịch với gcc the_file.s -mcmodel=large -Wl,-fuse-ld=gold


5
1<<30là đủ tốt cho C. Vì đây là trình biên dịch chương trình, kích thước tính bằng byte.
viraptor

2
@viraptor Hệ thống của tôi có 32GB RAM và vì những cú đá tôi đã cố gắng xây dựng mã của bạn. asquản lý để bàn giao ld, nhưng ldthất bại với điều này . Thậm chí -mcmodel=mediumdường như không giúp đỡ.
Idillotexist Idillotexist

2
hãy thử sử dụng goldtrình liên kết: gcc -fuse-ld=gold ...biên dịch / liên kết ... eek! Hoàn thành trong 1:29 (89 giây) và kích thước 1.073.748.000 byte.
lornix

2
Cuối cùng tôi đã có được điều này để lắp ráp trên Ubuntu 15.10 64 bit, với lời mời gcc -o g g.s -mcmodel=large -Wl,-fuse-ld=gold. Kiểm đếm cuối cùng : 4,294,975,320 bytes, với 32 byte bổ sung được thêm vào độ dài chương trình cho -mcmodel=large -Wl,-fuse-ld=gold. Đáng lưu ý rằng tiêu đề là không chính xác; nguồn là 29 byte (không thêm cờ bổ sung).
Mego

3
Bằng cách trả lại phân bổ lên đến 1<<33, tôi đã kết thúc với một 8,589,942,616byte thực thi.
Mego

60

Đây là câu trả lời C của tôi từ năm 2005. Sẽ tạo ra nhị phân 16TB nếu bạn có 16TB RAM (bạn không).

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
"Sẽ tạo ra nhị phân 16TB nếu bạn có RAM 16TB (bạn không)." - tôi cũng không có ổ cứng 16TB! Tôi thực sự không thể xác minh cái này, nhưng dù sao thì nó cũng rất tuyệt.
Dave

5
Tôi tình cờ phát hiện ra cái này và xem trình biên dịch lật đổ khi nó hết không gian địa chỉ.
Joshua

8
Vui lòng KHÔNG cố gắng đánh gôn mục này; chơi golf đánh bại ý định của mẫu mã và không có lợi ích điểm nào để làm như vậy dù sao đi nữa. Mã đã là GPL vào năm 2005.
Joshua

6
@BenVoigt Bất kể, chỉnh sửa mã của người khác không bao giờ được chấp nhận ở đây. Để lại một bình luận nếu có một vấn đề. Bài đăng meta có liên quan: meta.codegolf.stackexchange.com/questions/1615/iêu
Mego

2
@Joshua: Kiểm tra chênh lệch markdown. Mego chỉ thêm gợi ý nổi bật.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

25

Bộ tiền xử lý C cũ: đầu vào 214 byte, đầu ra 5 MB

Lấy cảm hứng từ bộ tiền xử lý trong thế giới thực của tôi thất bại ở đây .

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

Các thí nghiệm cho thấy rằng mỗi cấp độ của #defineý chí (như mong đợi) làm cho sản lượng lớn hơn khoảng mười lần. Nhưng vì ví dụ này mất hơn một giờ để biên dịch, tôi không bao giờ tiếp tục "G".


9
Điều này giống như một quả bom xml
một tai nghe

9
Cụ thể đó là một triển khai của "Tỷ tỷ cười" ban đầu.
mınxomaτ

Điều này là điên rồ nhưng đơn giản.
Vahid Amiri

2
Ồ, điều này thực sự gây ra một segfault trong GCC 4.9 và Clang. Bạn đã sử dụng trình biên dịch nào?
Dave

1
@Dave: Lạ thật. Khi tôi biên dịch bằng make, nó sẽ biên dịch, nhưng nếu tôi gõ chính xác cùng một lệnh sử dụng, nó sẽ gặp sự cố. Và nó dường như không liên quan đến các biến môi trường.
Thomas Padron-McCarthy

24

Java, nguồn 450 + 22 = 472 byte, tệp lớp ~ 1GB

B.java (phiên bản golf, cảnh báo trong quá trình biên dịch)

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 (phiên bản chưa được chỉnh sửa)

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

Biên soạn

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

Giải trình

Bom này sử dụng Bộ xử lý chú thích. Nó cần 2 lượt biên dịch. Pass đầu tiên xây dựng lớp bộ xử lý B. Trong lần truyền thứ hai, bộ xử lý tạo một tệp nguồn mới C.javavà biên dịch nó thành một tệp C.classcó kích thước 1,073,141,162byte.

Có một số hạn chế khi cố gắng tạo một tệp lớp lớn:

  • Tạo định danh dài hơn khoảng 64k kết quả trong : error: UTF8 representation for string "iiiiiiiiiiiiiiiiiiii..." is too long for the constant pool.
  • Tạo nhiều hơn khoảng 64k biến / hàm cho kết quả: error: too many constants
  • Ngoài ra còn có giới hạn khoảng 64k cho kích thước mã của hàm.
  • Dường như có một giới hạn chung (lỗi?) Trong trình biên dịch java khoảng 1GB cho .classtệp. Nếu tôi tăng 16380lên 16390trong đoạn mã trên, trình biên dịch không bao giờ trả về.
  • Ngoài ra còn có giới hạn khoảng 1GB cho .javatệp. Tăng 16380lên 16400trong mã trên dẫn đến: An exception has occurred in the compiler (1.8.0_66). Please file a bug ...theo sau là a java.lang.IllegalArgumentException.

10
Khéo léo; về cơ bản, bạn đã tạo bộ tiền xử lý của riêng mình, trong giới hạn kích thước, bằng ngôn ngữ có trình biên dịch hỗ trợ bộ tiền xử lý tùy chỉnh. Đó là trong các quy tắc. Lớp cuối cùng chỉ có 0,5 GB đối với tôi, nhưng tôi có thể xác nhận phương thức.
Dave

Một ví dụ khác trong Java habrahabr.ru/post/245333 - nó sử dụng lồng nhau try..finally(mã trong khối cuối cùng được sao chép cho các trường hợp thông thường và ngoại lệ) và khối khởi tạo (mã từ khối khởi tạo được thêm vào mỗi hàm tạo)
Victor

Tôi thay thế äbằng một ivà điều chỉnh các con số. Bây giờ, quả bom sẽ tạo ra một lớp 1GB trên bất kỳ hệ thống nào mà không có bất kỳ vấn đề mã hóa nào. Tuy nhiên, bây giờ nó cần nhiều bộ nhớ hơn.
Sleafar

? mở rộng TypeEuity?!?
mèo


22

C, nguồn 26 byte, đầu ra 2.139.103.367 byte, chương trình hợp lệ

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

Được biên dịch bằng: gcc cbomb.c -o cbomb(gcc phiên bản 4.6.3, Ubuntu 12.04, ~ 77 giây)

Tôi nghĩ tôi sẽ thử xem tôi có thể tạo ra một chương trình hợp lệ lớn đến mức nào mà không cần sử dụng bất kỳ tùy chọn dòng lệnh nào. Tôi đã có ý tưởng từ câu trả lời này: https://codegolf.stackexchange.com/a/69193/44946 bởi Digital Trauma. Xem các ý kiến ​​ở đó là lý do tại sao điều này biên dịch.

Cách thức hoạt động: Việc constxóa cờ ghi khỏi các trang trong phân đoạn, vì vậy chính có thể được thực thi. Đây 195là mã máy Intel để trả lại. Và vì kiến ​​trúc Intel là ít endian, đây là byte đầu tiên. Chương trình sẽ thoát với bất kỳ mã khởi động nào được đặt trong thanh ghi eax, có thể là 0.

Nó chỉ có khoảng 2 gig vì trình liên kết đang sử dụng các giá trị được ký 32 bit cho các offset. Đó là 8 meg nhỏ hơn 2 gig vì trình biên dịch / trình liên kết cần một số không gian để hoạt động và đây là phần lớn nhất tôi có thể nhận được mà không có lỗi liên kết - ymmv.


3
Như một điều thú vị, đầu ra là 2.078.451 byte được nén với tỷ lệ nén tối đa = 1029: 1.
Zakipu

20

Boo , 71 byte. Thời gian biên dịch: 9 phút. Thực thi 134.222.236 byte

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

Sử dụng một macro R(cho Lặp lại) để làm cho trình biên dịch nhân số câu lệnh tăng lên một số lần tùy ý. Không có cờ biên dịch đặc biệt là cần thiết; chỉ cần lưu tệp dưới dạng bomb.boovà gọi trình biên dịch booc bomb.boođể xây dựng nó.


2**e-Cái này là cái gì? Hãy thử 9**e!
wchargein

1
@WChargin: Điều thú vị của siêu lập trình là bạn có thể dễ dàng tùy chỉnh nó như thế nào!
Mason Wheeler

Tôi gặp một chút rắc rối khi cài đặt boo, tôi sẽ xác nhận điều này khi tôi quản lý để cài đặt nó!
Dave

@Dave Bạn gặp rắc rối gì với nó?
Mason Wheeler

16

Kotlin , nguồn 90 byte, 177416 byte (173 KB) được biên dịch nhị phân 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)}}}}}}}}}}}

Về mặt kỹ thuật, bạn có thể làm điều này lâu hơn nữa bằng cách lồng biểu thức xa hơn. Tuy nhiên, trình biên dịch gặp sự cố StackOverflownếu bạn tăng đệ quy.


Tiền tố SI của bạn không đồng ý. Đó có phải là 177416 kilobyte = 173 MB hay 177416 byte = 173 kB không?
Ben Voigt

1
@BenVoigt Cảm ơn bạn đã chỉ ra rằng: D
TheNumberOne

Thật ấn tượng, có +1
J Atkin

Để biên dịch Kotlin 1.2.20, chúng ta cần xóa một độ sâu và ~ 104kB. Phiên bản nào bạn đã sử dụng ban đầu?
TWiStErRob

15

C ++, 214 byte (không cần tùy chọn biên dịch đặc biệt)

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

Đây là một đệ quy mẫu hai chiều khá đơn giản (độ sâu đệ quy đi theo căn bậc hai của tổng số mẫu được phát ra, do đó sẽ không vượt quá giới hạn nền tảng), với một lượng nhỏ dữ liệu tĩnh trong mỗi một.

Tệp đối tượng được tạo với g++ 4.9.3 x86_64-pc-cygwin2567355421 byte (2.4GiB).

Việc tăng giá trị ban đầu trên 80 sẽ phá vỡ trình biên dịch gg cygwin (quá nhiều phân đoạn).

Ngoài ra, 99999có thể được thay thế bằng 9<<19hoặc tương tự để tăng kích thước mà không thay đổi mã nguồn ... nhưng tôi không nghĩ mình cần sử dụng nhiều dung lượng đĩa hơn mức tôi đã có;)


Đã được xác nhận (trên thực tế, đó là 2,56GB với tiếng kêu), nhưng nó cần một -ccờ biên dịch để dừng trình liên kết (2 byte thêm) và tôi không chắc mình có thể chấp nhận đầu ra .o (không phải một trong những cái tôi đã liệt kê). Tuy nhiên, tôi thích nó, vì vậy +1.
Dave

@Dave: tập tin gcc .o có định dạng ELF không?
Ben Voigt

Không chắc. Họ không bắt đầu bằng số ma thuật ELF khi tôi tạo chúng. Tôi sẽ điều tra sau.
Dave

@Dave: Chà, cygwin gcc không tạo tệp ELF. Linux gcc dường như (mặc dù tôi đang xem một từ một đoạn mã khác)
Ben Voigt

Có, GCC 5.2.1 trên Kubfox thực sự đang tạo tệp ELF, nhưng nó chỉ có 9 MB! Không chắc chắn làm thế nào nó quản lý để nén nó rất nhiều so với các trình biên dịch khác. Có thể GCC 4.9 sẽ tạo tệp ELF 2GB.
Dave

6

Scala - nguồn 70 byte, kết quả 22980942 byte (sau jar)

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

Điều này tạo ra 9 5 (khoảng 59.000) tệp lớp chuyên biệt, đóng gói vào một hũ khoảng 23 MB. Về nguyên tắc, bạn có thể tiếp tục nếu bạn có một hệ thống tệp có thể xử lý nhiều tệp đó và đủ bộ nhớ.

(Nếu phải bao gồm lệnh jar, thì đó là 82 byte.)


Tôi không thể biên dịch nó : error: java.lang.OutOfMemoryError: GC overhead limit exceeded. Bạn cũng có thể tài liệu lệnh cần thiết để biên dịch?
P.Péter

@ P.Péter - Bạn cần cung cấp cho trình biên dịch nhiều bộ nhớ hơn, ví dụ như scalac -J-Xmx12G X.scalanhững gì tôi đã sử dụng. Tôi đã không kiểm tra xem nó thực sự cần bao nhiêu.
Rex Kerr

vẫn không biên dịch, thật đáng buồn :( 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 foundBạn có thể chỉ định phiên bản scala và java (cũng có thể là nền tảng không)? Tôi đã sử dụng scalac 2.9.2 và OpenJDK 1.8.0_66-Internal-b17, trên 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 cho -cin gcc bomb.c -o bomb.o -c; đầu ra: 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, cách nhiều hơn bạn có thể mong đợi từ điều này

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

Điều này giống như câu trả lời của Mason Wheeler với một vài thay đổi nhỏ (??). Bạn đã đạt được cùng một câu trả lời một cách độc lập hay có điều gì quan trọng trong các giá trị bạn đã thay đổi (nếu vậy, vui lòng chỉnh sửa câu trả lời để giải thích lý do tại sao chúng quan trọng).
Dave

0

Con trăn 3:

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

Bom Tết


2
Bạn nên cho biết đầu ra có bao nhiêu byte, để xem mục nhập của bạn so với các mục khác.
Sanchise

Chào mừng đến với PPCG! Có vẻ như bạn đã vô tình tạo hai tài khoản và đăng câu trả lời này hai lần. Tôi đã xóa câu trả lời khác. Như Sanchises đã nói, thử thách này được ghi điểm bởi quy mô của chương trình được biên dịch . Vì vậy, bạn nên bao gồm kích thước đó trong câu trả lời của bạn vì đó là điểm chính. Cũng lưu ý rằng chương trình thực tế sẽ không lớn lắm, chỉ có biểu thức bạn đang tạo trong bộ nhớ, vì vậy bạn có thể muốn nghĩ về một cách tiếp cận khác.
Martin Ender

1
@MartinEnder do cách Python đánh giá một số biểu thức tại thời gian biên dịch và lưu trữ các số ở độ chính xác tùy ý, điều này (về lý thuyết) sẽ có một thực thi khá lớn. Nhưng như Aleksi Torhamo đã lưu ý (người đã sử dụng kỹ thuật tương tự cho một phần câu trả lời của anh ta), điều này có giới hạn ở khoảng 2GB, vì vậy tôi hy vọng rằng mã này được viết có thể sẽ không được biên dịch (mặc dù tôi đã không kiểm tra ). Nếu OP có thể biên dịch nó và đăng kích thước đã biên dịch (cùng với lệnh cần thiết để tạo nó), thì nó hợp lệ. Sự giống nhau với câu trả lời hiện có của Aleks giống như sự trùng hợp với tôi.
Dave
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.