我是一名开发人员,我不想做自己的工作。我从XKCD知道,最好的借口是代码的编译。因此,我认为我需要一些可以永久编译的代码!而且由于我很懒并且不想键入太多内容,因此必须使用尽可能短的代码来完成。
因此,您的任务是编写一个在语法上有效但会导致编译器进入无限循环的程序。
技术指标
- 显然,您必须使用具有编译器的语言。
- 指定每个解决方案中使用的实现。
- 这是代码高尔夫球,因此最短的有效解决方案(以字节为单位)获胜。
- 编译器可以终止以耗尽内存或堆栈空间。
我是一名开发人员,我不想做自己的工作。我从XKCD知道,最好的借口是代码的编译。因此,我认为我需要一些可以永久编译的代码!而且由于我很懒并且不想键入太多内容,因此必须使用尽可能短的代码来完成。
因此,您的任务是编写一个在语法上有效但会导致编译器进入无限循环的程序。
Answers:
`ÿ
您可以在此处在线进行测试,但我不建议您这样做,因为它将冻结您的浏览器。
Japt使用shoco库来压缩字符串。反引号告诉编译器解压缩所有内容,直到下一个反引号或文件末尾为止。每个字节执行以下操作:
00-7F
保持原样。80-BF
每个变换到共同的小写的两字母对(at
,oo
,th
等等)。C0-DF
每个使用下一个字节并转换为一个公共的四字母字符串。E0-EF
每个都占用接下来的三个字节,并转换为“公用”八字母字符串(Whererer
从此处开始并从此处下坡)。F0-F7
中断解压缩器,尽管它仍然返回所有数据直到中断字节。F8-FF
使解压缩器进入无限循环。我不确定为什么会这样,因为我对shoco库的内部工作不是很熟悉(并且JavaScript代码是完全不可读的),但是在这种情况下非常方便。我不认为还有其他方法可以弄乱Japt编译器,但您永远不会知道...
多亏了wchargin节省了一堆字节
克里斯·H节省了一个字节
\input tikz
\tikz\pic
我在做作业时实际上是偶然遇到的。我花了相当长的时间等待它编译,然后才意识到发生了什么。
这包括两个部分:
\input tikz
这将加载TikZ包
和:
\tikz\pic
这将启动\tikz
环境和绘制命令。
pdflatex编译器在上遇到问题\tikz\pic
,并进入交互模式,导致其无限期停止。
\draw l\end {document}
!扫描使用\tikz@next.
pdflatex 3.1415926-2.5-1.40.14(TeX Live 2013 / Debian)时文件结束。tikz 2010/10/13 v2.10。这是apt install texlive-full
Ubuntu 14.04的标准配置。
pdfTeX 3.14159265-2.6-1.40.17 (TeX Live 2016)
确实确实无限期地循环。感谢您的提示。
\pic
而不是\ draw` 来保存一个字节-完全相同的行为(使用tikz 1.142测试)
\def\a{\a}\a
(12个字节)怎么了?还是因为这是代码高尔夫,并且~
默认情况下处于活动状态\def~{~}~
(9字节)?
#include __FILE__
循环大约200次后,编译器通常会放弃。
DOM构建是否算作编译步骤?如果是这样,则x.htm
:
<iframe src=x.htm>
<?include __FILE__;
。
class A<T>{}class B<T>extends A<A<?super B<B<T>>>>{A<?super B<A>>a=new B<>();}
这以a终止,StackOverflowError
因为通用解析系统无法确定用于解析其他通用名称的根。
A<T>
仅在那里有一个1字母的父母。这是通用的。我本可以使用的List
,但是4个字母的导入和重复太长了。B<T>
声明一个基本的泛型。B extends A
必须具有B
和之间的层次结构A
。extends A<A>
在上创建自我参考A<T>
。A<? super B>
触发对泛型的查找 A<T>
B<B<T>>
在创建一个自引用B<T>
。A<...> a=new B<>()
强制使用泛型,而不是简单地定义泛型,在编译B
时(而非之后)强制执行解析。A<?super B
创建一个非自我引用,因此在的泛型中我们同时引用了一种类型和另一种类型A
。B<A>
创建一个非自我引用,因此在的泛型中我们同时引用了一种类型和另一种类型B
。现在,该类型A
具有泛型类型A
和B
,但是要选择哪个呢?忘记自我,让我们尝试解决B
。平安
好,B
具有泛型类型A
和B
,但它是被选择?忘记自我,让我们尝试解决A
。傍
确实无法避免这种递归,因为存在合法的情况,例如A<B<A<B<A<B<Object>>>>>>
:例如JSON对象:List<Map<String,Map<String,List<Map<String,List<String>>>>>>
。
$ javac NoCompile.java
The system is out of resources.
Consult the following stack trace for details.
java.lang.StackOverflowError
at com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:3260)
at com.sun.tools.javac.code.Types$23.visitClassType(Types.java:2587)
at com.sun.tools.javac.code.Types$23.visitClassType(Types.java:2579)
at com.sun.tools.javac.code.Type$ClassType.accept(Type.java:554)
at com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:3260)
at com.sun.tools.javac.code.Types$23.visitClassType(Types.java:2592)
at com.sun.tools.javac.code.Types$23.visitClassType(Types.java:2579)
at com.sun.tools.javac.code.Type$ClassType.accept(Type.java:554)
在我的系统上,堆栈跟踪在显示1024行之后停止,实际上这4条相同的行重复了256次,因此证明了无限递归。我会全力以赴。
interface
+ implements
替换class
+ extends
。Long
为A
(两次)。new B<A>()
→ new B<>()
)。class A<T>{}class B<T>extends A<A<?super B<B<T>>>>{A<?super B<A>>b=new B<>();}
B
的泛型A
包含对B的泛型的不确定的引用,而该泛型又包含对B的泛型的不确定的引用。当解析程序无法决定时,它将检查包含的引用,但此处两个泛型都互相引用在不可判定的方式(主要是由于自身的引用和super
关键字于是两人之间的仿制药的分解实际上平pongs。
public @interface X {@X(x=X.class)Class<? extends X> x();}
...但是我很快意识到为什么这行不通。
感谢KonradRudolph节省了一个字节
另存为Makefile
并由调用make
:
x:;make
这将对找到的第一个目标产生无限的构建递归"x"
。
不用说,您并不是真的不想在生产服务器上运行此fork炸弹。:-)
make
make[1]: Entering directory `/path/to/my/dir'
make
make[2]: Entering directory `/path/to/my/dir'
make
make[3]: Entering directory `/path/to/my/dir'
make
make[4]: Entering directory `/path/to/my/dir'
make
make[5]: Entering directory `/path/to/my/dir'
make
make[6]: Entering directory `/path/to/my/dir'
make
make[7]: Entering directory `/path/to/my/dir'
make
...
KonradRudolph建议:
x:;$_
$_
是对上一个命令的最后一个参数的引用。更具体地说,这里将其解析为要执行的命令的绝对路径,它make
本身就是路径。
在真正的Bash环境中应该可以正常工作,但在Windows + MinGW上则不能。
make
确实可以编译 Makefile(它只是解释它)。
template<class T>class a{a<T*>operator->();};a<int>i=i->b;
这会递归地创建class a
具有不同模板参数的实例。GCC 7.0在900个递归级别之后停止运行,并出现了很多关于operator->
私有的错误,但是例如ICC 17和Microsoft(R)C / C ++ Optimizing Compiler 19 在Godbolt上超时。
这样做的问题是,可能所有的编译器都会在某个时间点耗尽内存,因此即使没有递归限制,这种情况也会停止。Clojure答案也可能相同。
编辑:bolov保存了2个字节-谢谢
a<int>i=i->b;
operator->
默认情况下,该类是private。在结构内它是公共的,因此i->b
可以访问它。
BEGIN{{redo}}
现在保存了2个字节:@Zaid让我想起了一种在Perl中执行循环的简洁方法。
这非常简单:它只安装了一个带有无限循环的解析器挂钩,从而使代码解析花费了无限长的时间。(Perl的优点在于,它允许您在解析的中间运行任意代码;解析器挂钩是在Perl本身中指定的,并且经常用于执行诸如导入库之类的操作或更改要处理的标识符的解析规则一个关键字。)在线试用!上面的链接提供了一个-c
选项(编译代码以验证语法的正确性,但不运行它),以证明无限循环在编译时发生。
如果您想知道脚本语言中的“编译时间”:Perl实际上会编译为字节码,然后运行字节码,但这是一个细节,在编程时很少涉及。该-MO=
命令行选项的家庭可以用来做的事情比运行它其他的字节码(虽然不是这个方案,因为无限循环发生,可以产生字节码之前)。
a:goto a
看起来也不错(可悲的是字节数相同)。
BEGIN{{redo}}
将为您节省几个字节
int f(auto p){f(&p);},a=f(0);
它使用将来的自动功能参数。它是在C ++ 17中提出的,但我认为它没有实现。gcc
但是支持它作为扩展。
基本上
void foo(auto p);
相当于
template <class T>
void foo(T p);
该代码尝试f
使用不同的模板参数递归实例化。gcc
失败于
致命错误:模板实例化深度超过最大值900(使用-ftemplate-depth =增加最大值)
有了-ftemplate-depth=10000
它,我就可以在Godbolt上吐出“杀死-处理时间超出”。
检查它在godbolt
Quentin保存了1个字节。谢谢。
int
为返回类型:)
auto
函数参数并没有进入C ++ 17。也不int f() { ... }, a;
是我上次检查时的合法声明。(您不能将函数声明与这样的变量声明混合使用。)您在这里获得的是C ++的一种非常特定于GCC的方言。在这种情况下,这并不意味着有什么问题。:)
#.(loop)
编译器将尝试读取表单,并会遇到Sharpsign-dot Reader宏,该宏在读取时评估代码并将其结果用作表单进行编译。在这里,正在执行的代码是一个无限循环。
\def~{~}~
TeX通过扩展宏来工作。在大多数情况下,TeX的宏(也称为控制序列)具有一定的形式,\name
但也可以将某些字符定义为宏,这些字符称为活动字符。~
默认情况下,该字符在普通TeX中处于活动状态,因此无需进一步声明即可用作宏名。的\def~{~}
在上述定义~
,使其膨胀到~
。也就是说,每当TeX遇到~
它时,它都会用替换它~
,然后重新检查替换,这意味着它遇到的全新出现~
并用替换它~
。这定义了无限循环。然后,所需要做的就是启动循环,这就是最后的动作~
。
在编辑中添加
要对此进行正确编译,请按以下方式调用:
pdftex -ini "&pdftex \def~{~}~"
该-ini
旗说,pdftex
应该编制一个新的格式文件。这是一组预编译的定义,可在以后调用TeX来加快文档处理速度时加载这些定义(LaTeX2e是其中的一个示例)。我猜想这加&pdftex
了几个字节,使总数达到17。
pdftex
程序视为“解释” TeX输入,以将PDF生成为“输出”,这与g++
程序“解释” C ++输入以将.exe文件生成为“输出”的方式相同。;)
a= $(let a='a':a in[|a|])
一个简单的Haskell元程序,它定义一个无限值并尝试在编译时计算该值。
调用ghc -XTemplateHaskell <file.hs>
(对于编译器,参数为+17)
$(let a=a in a)
(32字节)?
let a = a in a
将重写为异常,这只会导致编译器错误,而不是无限循环。(尽管也许这可以与其他Haskell编译器一起使用,但是我手头上没有尝试)
Exception when trying to run compile-time code: <<loop>>
,它在解释器和编译时都给出了...从技术上讲,上面的代码也死了,但有异常,但是堆栈溢出,规范明确允许-如果您拥有无限的内存,它将永远循环下去。该<<loop>>
异常在我的计算机内存不足之前触发。
for(;;){}
将上面的代码放在build.gradle
文件中。Gradle使用groovy作为其基本语言,因此我们在这里实际上是在谈论groovy,但是由于问题是关于构建时间,我认为gradle会更合适。
使用上面的代码运行任何gradle构建命令,将打印出pointy-hair-boss兼容的构建状态行:
$ gradle tasks
> Configuring > 0/1 projects > root project
如果您打算加薪,请为以下项添加调试-d
标志:
$ gradle -d tasks
14:56:25.522 [INFO] [org.gradle.internal.nativeintegration.services.NativeServices] Initialized native services in: .gradle/native
14:56:25.757 [DEBUG] [org.gradle.launcher.daemon.client.DaemonClient] Executing build 84908c0d-f28d-4c57-be61-40eaf0025e16.1 in daemon client {pid=27884}
14:56:25.761 [DEBUG] [org.gradle.internal.remote.internal.inet.InetAddresses] Adding IP addresses for network interface tun0
14:56:25.762 [DEBUG] [org.gradle.internal.remote.internal.inet.InetAddresses] Is this a loopback interface? false
14:56:25.762 [DEBUG] [org.gradle.internal.remote.internal.inet.InetAddresses] Is this a multicast interface? false
14:56:25.764 [DEBUG] [org.gradle.internal.remote.internal.inet.InetAddresses] Adding remote address /x:x:x:x:x:x:%tun0
14:56:25.764 [DEBUG] [org.gradle.internal.remote.internal.inet.InetAddresses] Adding remote address /x.x.x.x
14:56:25.764 [DEBUG] [org.gradle.internal.remote.internal.inet.InetAddresses] Adding IP addresses for network interface eth1
14:56:25.764 [DEBUG] [org.gradle.internal.remote.internal.inet.InetAddresses] Is this a loopback interface? false
14:56:25.764 [DEBUG] [org.gradle.internal.remote.internal.inet.InetAddresses] Is this a multicast interface? true
14:56:25.764 [DEBUG] [org.gradle.internal.remote.internal.inet.InetAddresses] Adding remote address /x:x:x:x:x:x:%eth1
14:56:25.764 [DEBUG] [org.gradle.internal.remote.internal.inet.InetAddresses] Adding remote address /x.x.x.x
14:56:25.764 [DEBUG] [org.gradle.internal.remote.internal.inet.InetAddresses] Adding remote multicast interface eth1
14:56:25.764 [DEBUG] [org.gradle.internal.remote.internal.inet.InetAddresses] Adding IP addresses for network interface lo
<snip>
14:57:07.055 [DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Releasing lock on daemon addresses registry.
14:57:07.056 [DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Waiting to acquire shared lock on daemon addresses registry.
14:57:07.056 [DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Lock acquired.
14:57:07.056 [DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Releasing lock on daemon addresses registry.
> Configuring > 0/1 projects > root project
除了看起来非常复杂之外,它还更新了一组新的:
15:07:57.054 [DEBUG] [org.gradle.launcher.daemon.server.Daemon] DaemonExpirationPeriodicCheck running
15:07:57.054 [DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Waiting to acquire shared lock on daemon addresses registry.
15:07:57.054 [DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Lock acquired.
15:07:57.055 [DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Releasing lock on daemon addresses registry.
15:07:57.055 [DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Waiting to acquire shared lock on daemon addresses registry.
15:07:57.055 [DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Lock acquired.
15:07:57.055 [DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Releasing lock on daemon addresses registry.
每隔10秒就会更新一次状态行,使它看起来像是在忙于进行重要的技术工作。
term_expansion(_,_):-repeat,1=0.
term_expansion/2
是在实际编译代码以将源代码中的某些术语转换为其他术语之前,编译器自动调用的东西。
在这里,我们介绍一个新的规则term_expansion/2
:repeat,1=0.
。
repeat/0
是始终成功的谓词,并且提供了无限数量的选择点。
1=0
试图统一1
使用0
,这是永远false
。这将导致编译器回退到repeat
(因为它总是提供一个选择点)并重试1=0
,依此类推。
.PHONY:x
$(MAKEFILE_LIST):x;sleep 1;touch $@
我不能为此索赔。它源自罗伯特·梅克伦堡(Robert Mecklenburg)的《用GNU Make管理项目:GNU Make在构建任何东西上的力量》一书。
当make执行此makefile时,它会看到makefile已过期(因为.PHONY目标已过期,因此它执行touch命令,该命令会更新makefile的时间戳。然后make重新读取该文件并发现makefile已经过时了。。。
我不喜欢其他的“答案”,因为它不使用递归。在我的VM上,另一个Make答案继续进行分支过程,并且在大约7,000深度处,VM陷入无响应的停止状态。但是,有了这个答案,它可以无限期地继续工作而不会消耗系统资源。您确实可以轻松完成此构建。我已经进行了1,000,000次迭代,并且没有明显的系统降级。
注意,我必须添加,sleep 1
这样makefile时间戳实际上每次都会更新。您可以将其更改为sleep 0.01
如果希望它可以更快地遍历迭代。
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="X">
<Exec Command="msbuild"/>
</Target>
</Project>
将此文件另存为带有.proj
扩展名的文件,然后msbuild
在命令提示符下运行。MSBuild将运行其唯一的目标,该目标只是生成另一个msbuild
进程。
Compile[{},Evaluate@While[True,]]
该代码将尝试在编译之前象征性地评估参数,并且参数本身是一个无限循环。While函数的第二个参数为空,因为它并不重要。
Compile
通话期间还是在通话之前发生?
{-#LANGUAGE FlexibleContexts,UndecidableInstances#-}
data A x=A
class C y where y::y
instance C(A(A x))=>C(A x)where y=A
main|A<-y=pure()
从理论上讲,它进入无限循环的方式与C ++方法几乎相同:将多态方法y
实例化为越来越复杂的类型。实际上,默认分配的堆栈大小实际上会很快溢出:
$ ghc-7.10 wtmpf-file14146.hs
[1 of 1] Compiling Main ( wtmpf-file14146.hs, wtmpf-file14146.o )
wtmpf-file14146.hs:5:9:
Context reduction stack overflow; size = 101
Use -fcontext-stack=N to increase stack size to N
C (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A t0))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
In a stmt of a pattern guard for
an equation for ‘main’:
A <- y
In an equation for ‘main’: main | A <- y = pure ()