整数を419378回インクリメントするとMacのg++が死ぬ
や
C++でアスタリスクをつけすぎると端末が落ちる
にインスパイアされて。
Go が Go で書かれているのであれば、スタックが可変長なので相当しぶといと予想していた。
で、まずは括弧。
(((((1)))))
a = [*1..1000000]
p(a.bsearch do |n|
exp = "("*n + "1"+")"*n
File.open( "hoge.go", "w" ){ |f| f.puts( <<"GOLANG" ) }
package main
import (
"fmt"
)
func main() {
fmt.Println(#{exp})
}
GOLANG
begin
"1" != %x( go run hoge.go ).strip
rescue
true
end
end)
#=>871538
87万。なかなかしぶとい。
もうちょっと(億とか)行くと予想していたので、予想は外れ。
1+1-1+1-1+1-1+1-1+1-1
a = [*1..1000000]
p(a.bsearch do |n|
exp = "1"+"+1-1"*n
File.open( "hoge.go", "w" ){ |f| f.puts( <<"GOLANG" ) }
package main
import (
"fmt"
)
func main() {
fmt.Println(#{exp})
}
GOLANG
begin
"1" != %x( go run hoge.go ).strip
rescue
true
end
end)
#=>68899
7万弱。「1」の数なら14万弱。
括弧よりも 1+1-1… の方がしぶといと予想していたので、こちらも予想は外れ。
そういうものか。
func()int { return func()int { return func()int { return 1}()}()}()
a = [*1..1000000]
p(a.bsearch do |n|
exp = "func()int { return "*n+"1"+"}()"*n
File.open( "hoge.go", "w" ){ |f| f.puts( <<"GOLANG" ) }
package main
import (
"fmt"
)
func main() {
fmt.Println(#{exp})
}
GOLANG
begin
"1" != %x( go run hoge.go ).strip
rescue
true
end
end)
#=>102
およそ百。少ない。
まあ、機械生成でもこの文脈で死ぬようなコードは吐きにくいと思うので無害だと思う。いわんや人間に於いてをや。
ちなみに、
runtime.morestack: nosplit stack check too deep
runtime.morestack: nosplit stack overflow
というエラーが出る。
nosplit stack とはなんだろうか。
<-<-<-<-<-<-<-<-<-<-
a=[*3..10000]
p( a.bsearch do |n|
types = Array.new(n-1){ |i|
"type c#{i+1} chan c#{i}"
}.join("\n")
makes=Array.new(n){ |i|
"v#{i} := make(c#{i})"
}.join("\n")
funcs=Array.new(n-1){ |i|
"go func(){ v#{i+1}<-v#{i} }()"
}.join("\n")
File.open( "hoge.go", "w") do |f|
f.puts %Q!package main
import "fmt"
type c0 chan int
#{types}
func main() {
#{makes}
go func(){ v0<-1 }()
#{funcs}
fmt.Println(#{"<-"*n}v#{n-1})
}!
end
begin
ng = "1"!=%x( go run hoge.go ).strip
p [ n, ng ? "NG" : "okay"]
ng
rescue
p [ n, "NG"]
true
end
end)
n=10000 まで試したけど死ななかった。それ以上は実行時間がかかりすぎるので試していない。
ちなみに、n=5 のときのコードは( フォーマットすると )
package main
import "fmt"
type c0 chan int
type c1 chan c0
type c2 chan c1
type c3 chan c2
type c4 chan c3
func main() {
v0 := make(c0)
v1 := make(c1)
v2 := make(c2)
v3 := make(c3)
v4 := make(c4)
go func() { v0 <- 1 }()
go func() { v1 <- v0 }()
go func() { v2 <- v1 }()
go func() { v3 <- v2 }()
go func() { v4 <- v3 }()
fmt.Println(<-<-<-<-<-v4)
}
こんな感じ。
他の処理系
-
- ruby
-
- python
- node.js