整数を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
广告
将在 10 秒后关闭
bannerAds