[HN Gopher] 16 bytes of Python that compile to 32 terabytes of b...
       ___________________________________________________________________
        
       16 bytes of Python that compile to 32 terabytes of bytecode (2016)
        
       Author : azhenley
       Score  : 131 points
       Date   : 2021-02-16 19:22 UTC (3 hours ago)
        
 (HTM) web link (codegolf.stackexchange.com)
 (TXT) w3m dump (codegolf.stackexchange.com)
        
       | [deleted]
        
       | tylerhou wrote:
       | Someone asked (and deleted their comment while I was writing my
       | reply):
       | 
       | > How does this compile in another language such as C?
       | 
       | It doesn't; the C language doesn't implement arbitrary size
       | integers, and therefore most C compilers won't fold constants of
       | such large size.
       | 
       | If you used a library that provided BigInts (arbitrary size
       | integers), and and the library also provided a compiler extension
       | to fold BigInt expressions at compile time, then you would likely
       | get a large executable as well (most of the size would come from
       | the data section).
        
         | falcolas wrote:
         | Well, you could probably abuse preprocessor macros and make
         | something similar in C.
        
           | azhenley wrote:
           | I can't find my favorite C macro bomb, but this same post has
           | a C answer using defines:
           | https://codegolf.stackexchange.com/a/69413/4270
           | 
           | The C++ template answers are particularly scary...
        
           | shakna wrote:
           | Not entirely of the same vein, but this C++ stacktrace bomb
           | is one of my favourites:                   struct x struct z<
           | x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(y,x(y><y*,x(y*w>v<y*,w,x{}
           | 
           | A tiny 79 bytes that explodes into a huge stacktrace that
           | takes an inordinate amount of time to finish processing.
        
             | colejohnson66 wrote:
             | How is this supposed to work?
        
               | phoe-krk wrote:
               | Try compiling it. The compiler will scream at you for a
               | _long_ long time.
               | 
               | Also see https://codegolf.stackexchange.com/questions/195
               | 6/generate-t...
        
               | colejohnson66 wrote:
               | Ah. I was confused by your usage of the word "stacktrace"
               | which, to me, means an exception stack trace, not an
               | error message. For those curious:                   $ g++
               | test.cpp 2>&1 > /dev/null | wc -l         10223622
               | 
               | _Ten million lines._
        
               | phoe-krk wrote:
               | Wasn't "my" usage per se since I'm not the original
               | comment author, but yes, I too find this term confusing
               | in this context. A stack trace to me usually means a
               | textual dump of a call stack printed from some point of
               | the program execution (usually an error site and/or a
               | breakpoint), not compiler output that contains no
               | information about the compiler's runtime stack.
        
               | Sharlin wrote:
               | In this case the error message contains information about
               | the compiler's _template instantiation stack_ which is
               | rather analogous to the stack trace of a recursive
               | function. But yeah, a somewhat nonstandard usage.
        
               | gpderetta wrote:
               | I would say that 'stacktrace' is appropriate.
               | 
               | The template expansion machinery is pretty much a purely
               | functional language and the compiler is the interpreter.
               | The stacktrace in this case is not of the interpreter
               | itself but of the program being executed.
               | 
               | In fact understanding that template error messages are
               | none other than execution stack traces is key to
               | understanding them.
        
           | Karliss wrote:
           | Even without abusing preprocessor or C++ templates you do
           | something as simple as global array char a[1ULL<<30]={1};
           | 
           | Initialize at least one member so that it gets placed in data
           | section instead of bss resulting in binary size more or less
           | the same as array. Although at least on my system various
           | parts of toolchain start to break down once you reach 2GB
           | limit.
        
             | shakna wrote:
             | The plain C equivalent to the above, changing the "command"
             | part to be something valid:                   const
             | main[255<<21]={195};
             | 
             | You can also get around the 2Gb limit by using the -mcmodel
             | flag, such as 'gcc -mcmodel=medium FILE'. But then actually
             | compiling the thing takes a long time and a heck of a lot
             | of memory:                   const main[-1u]={195};
        
       | eesmith wrote:
       | I thought that problem got fixed a few releases ago. Maybe 3.7,
       | when some of the peephole optimizer logic was moved to the AST?
       | 
       | At the very least, I can't reproduce it.                 % cat
       | tmp.py       (1<<19**8,)*4**7       % python -m compileall tmp.py
       | % ls -l __pycache__/tmp.cpython-39.pyc       -rw-r--r--  1
       | eesmith  admin  167 Feb 16 12:21 __pycache__/tmp.cpython-39.pyc
       | 
       | Python 3.6 generates a 144 byte file. One of the comments says it
       | caused a problem in Python 3.3.5.
       | 
       | Another peephole optimizer gotcha that caused problems with older
       | Pythons is at https://bugs.python.org/issue30416 :
       | def tuple20():           return
       | ((((((((1,)*20,)*20,)*20,)*20,)*20,)*20,)*20,)*20
       | 
       | If you have Python 2.7 hanging about, try simply defining that
       | function - you can't even ^C it!
        
         | chias wrote:
         | I am also unable to reproduce it (Python 3.8.5)
        
         | jwilk wrote:
         | I can reproduce it with Python 3.5, but indeed not with 3.6.
        
         | PartiallyTyped wrote:
         | I can't reproduce in 2.7.16 and 3.7 either. The tuple20 is an
         | interesting one, using lists instead of tuples it doesn't
         | explode in size, at least in 2.7
        
       | chrisseaton wrote:
       | How is Python able to constant-fold at bytecode compile-time like
       | that? I thought operators were redefineable in Python? So could
       | they be redefined next time you load the bytecode and the
       | constant now invalid? Is that not the case?
        
         | wizzwizz4 wrote:
         | They're not redefinable on the built-in types. (Well, they
         | _are_ , but not officially.)
        
       ___________________________________________________________________
       (page generated 2021-02-16 23:00 UTC)