GCCの関数の引数の評価順序は右から左?!


はじめに

右から右からやってくる。僕はそれを左へと受け流す・・・というお笑いソングがありました。また、リバイバルしてるみたいですけど。
https://www.youtube.com/watch?v=f2kj6gOYPPI

なんと!GCCも右から左へと受け流していたのでした。

ご参考
https://cloud6.net/so/c/1927896

発端

自作Easy-ISLispはLispからGCCの拡張機能を利用したCコードに変換、GCCにより動的オブジェクトを生成、リンクする方式です。この度、ベンチマークテストをしていて、どうやらGCCの関数の引数の実行順序は左から右ではないらしいことがわかりました。ISLispは規格により引数は左から右へ評価することが定められています。ですからこれに依存した副作用を伴うコードも可能です。しかし、これがGCCでは成り立たないらしいのです。

実験

次のコードを書いて試してみました。


(defun foo ()
    (bar (format (standard-output) "~A " 1)
         (format (standard-output) "~A " 2)
         (format (standard-output) "~A " 3)))

(defun bar (x y z) nil)


インタプリタだと次のように期待通りです。


Easy-ISLisp Ver1.83
> (load "tests/order.lsp")
T
> (foo)
1 2 3 NIL
> 

ところがコンパイラだと


> (load "tests/order.o")
T
> (foo)
3 2 1 NIL
> 

対策

さあ、どうしましょう? GCCも左から右へと評価してくれるようなオプションがあると助かるのですが・・・

あのムーディーさんの歌、 左から左からだとなんだかサマにならないんでしょうね。