「プログラミング言語は速ければ速い程イイ」と言われる。
パッと聞くとそれは非常に魅惑的に聞こえる。
だからこそ、ランキング発表、みたいなモノがあるわけだよな。
それで「俺が使ってる言語は速い」とか、あるいは「この速い言語を使わないとダメだ」とか色々と葛藤が出てくるわけだ。
例えばとあるサーベイではランキング(Top 10)は次のようになっている。
断っておくけど、このテのサーベイってのは「本当にこの世に存在する全言語を調べたのか」と言うと、そういう保証はない。
他にも細かいトコを言うと、コーディングスタイルの問題がある。例えば言語Aで「メチャクチャ速くなるコードを書くテクニック」が言語Bで使える保証がない。コーディングスタイル自体にバイアスがあるわけだよ。
ある程度分かってる人になると、「まぁ、目安だよね」と考えるんだけど、そうじゃないと「こういうランキングが全て」と勘違いしかねないわけだ。
一般的に言うと確かに「インタプリタ実装」よか「コンパイラ実装」の方が速い・・・何度も言うけど「インタプリタ型言語」とか「コンパイラ型言語」っつーのがあるわけじゃねぇけどな。
例えば上のランキングを見ると、JavaとかMicrosoft系のC#とかF#はどうしてもC言語よりは遅くならざるを得ない・・・つまり、このテの言語は原理的にはインタプリタ上で動作するから、だ(※1)。
しかし、これは「実装の問題」であって「言語の問題」じゃない。
例えばかつてはGCJと言うJavaコンパイラ実装があって、必要に応じてネイティヴの(※2)マシン語を生成した。
実装によってコンパイラが生成するブツが違うんだ。
「分かってる人」があまりこのテのランキングを気にしないのは、例えば上のランキングで「C言語が一位ってどういう意味?」ってのを分かってるから、だ。
そう、シンタックスとして「C言語がある」ってのは誰でも分かるけど、そうじゃなくって「この世にはC言語実装がたくさんある」ってのを彼らは知っている。
全部のC言語のコンパイラ実装が同じ速度の実行ファイルを吐くわけじゃない。つまり「全部のC言語コンパイラ実装が一位」って事はあり得ないわけだ。当然だろ(笑)?
彼らは複数あるC言語のコンパイラ実装から自分の好みを選択する。当然その一つとして「一番速い機械語を生成するコンパイラ」を選んだり、あるいは、「GCCは末尾再帰最適化の機能があるからこれを使おう」とか、趣味に走ったりするわけだ(笑・※3)。
また、貴方が例えばC言語のコンパイラを作ったとして、「C言語のコンパイラを作った」 = 「実行速度1位になる機械語を吐き出すコンパイラになってる」わけではない。
要はプログラミング言語そのものとそのコンパイラの最適化(※4)は全く別の話なんだ。
一般的には、必ずしもプログラミング言語の構文設計と最適化は関係がない・・・いや、どっちかっつーと「便利機能を構文解析しやすいか否か」ってのはあるんだけど、大体「便利機能を搭載しようとする」と最適化が難しくなってコンパイラが吐き出すマシンコードは遅くなる(笑)。
つまり「ぼくのかんがえたさいきょうのげんご」はどうしても遅くなるし、じゃあ速度を追求出来るような構文にすると「書きづらいわ使いづらいわ」って話になる・・・いや、速度をマジで追求するなら「黙ってアセンブリ言語を使っとけよ」って話になるわけだ(笑)。それじゃあ困るから高級言語が生まれたわけだよな(笑)。
つまり、通常、「構文設計」そのものと「吐き出すマシン語のクオリティ」には殆ど関係がない、って事になるわけだ。あるいは、「律速」って言う意味では限界がある。
そう、ここまで見れば大体分かるだろ?「プログラミング言語」として定義されるモノとそのコンパイラ実装が生成した「実行ファイルの速度」には・・・全く関係がない、たぁ言わんが殆ど関係がないんだ。あるのは「特定の実装」の「最適化」が上手く行ってるのか否か、って事だけ、なんだよな、大まかに言うと。
上の言語ランキングをもう一回見てみよう。
- C -> ISO(国際標準化機構)で言語仕様が定義されている。 -> 複数実装アリ
- C++ -> ISO(国際標準化機構)で言語仕様が定義されている。 -> 複数実装アリ
- Rust -> 仕様書ナシ。Pythonと同様の「仕様=実装」言語。
- Fortran -> ISO(国際標準化機構)で言語仕様が定義されている。現在の標準は2019年制定のFortran 2018 。-> 複数実装アリ
- Julia -> 仕様書ナシ。Pythonと同様の「仕様=実装」言語。
- Ada -> ISO(国際標準化機構)で言語仕様が定義されている。現在の標準は2012年制定。
- Java -> Oracleによって言語仕様は公開されている。ただし、権威ある仕様書ではない。
- C# -> ECMA/ISO(国際標準化機構)で言語仕様が定義されている。現在では、大本のMicrosoftによる実装以外、Linuxで使えるMonoと言う実装がある。
- F# -> IETFによって言語仕様が定義されている(!)。なお、F#はフランスで開発されたOCamlの方言。
- Pascal -> ISO(国際標準化機構)で言語仕様が定義されている。 -> 複数実装アリ(減りつつあるが)
何度か言ってるが、プログラミング言語には「言語仕様がある」言語とそれが存在しない言語がある(※5)。
「今後十何年か使い続けたい」場合、やっぱり「言語仕様が制定されている」プログラミング言語の方が有利だ。そうじゃないと「一体いつ如何なる時に実装がいきなり変更になるか」分かったモンじゃない。
もちろん、いつぞや書いた通り、C言語みたいに状況がちとわやくちゃなプログラミング言語もあることはあるが、「長く使いたい」のなら、いずれにせよ、「公式に言語仕様が決められてるプログラミング言語」をチョイスした方がいい(※6)。要は「プログラミング言語の選択」は必ずしも「生成するバイナリの速さ」だけで決めるモノでもない。当然だよな。
もちろん、「生まれたばっかのプログラミング言語」がいきなり国際規格で「標準化される」なんつー事はない。結構時間がかかるんだよ。普及するにも時間がかかるし、そして「標準化の必要性が出てくる」まで時間もかかる。
例えばRustなんかは良い言語だとは思うんだけど、まだまだ実績が足りないだろう。今のトコまだ、個人的な観察範囲の限界では、Mozilla回りに留まってる、って印象だ。いや、評価が高いのは知ってるし、実際C言語プログラミング的なストレスが無いように色々と面白い機能がある。尖った人が好きだろうな、とは思うけど、一般的には「まだ時期尚早」って感触だ。
多分このランキングだと、だから「速さが必要で」とかなるんだったらC++かC#が選択肢になる、っつーのがフツーの結論(これまた「フツー」がいいかどうかは知らんが)になるんじゃないか。
次に考えるのが、やっぱり「速い言語になればなるほどプログラミングがメンドくなる」って問題がある。要するに書く量が増えていく。
企業的にチームを作って、例えば100人単位とか(笑)、そういうんでプログラムをします、ってぇのならいざ知らず、一人でやってる、とかだと必然的にコーディング量が多いと大変でしょ。
一つの例としてはガベージコレクタがあるかどうか。一般的には速い実行ファイルを吐き出す言語処理系はガベージコレクタを持たない。プログラマ自身がメモリ管理をせなアカン。
ところがメモリ管理をせんとどうなるか。たまに経験あるだろ?なんかPC点けっばにしてアプリ起動したまま寝落ちした、とかさ(笑)。朝起きて、PC弄ってみればなんかマウスの挙動がヘンだ。動きがカクカクするしクローズボタン押しても反応せん、とか(笑)。
大体のトコ、これが起きる原因がメモリーリークだ。起動させっぱなしのソフトウェアのどっかで「メモリ管理」が間違ってて、メモリ領域を使い切りそうになっててパフォーマンスが落ちる、ってアレだわ(笑)。慌ててWindowsのタスクマネージャーを起動してKillせなアカン、とか言うヤツ。
「必ず間違える」し「メンド臭い」。プログラミング言語側にガベージコレクタがあればこういうプログラムにはまずならないんだけど、イキって「自分でメモリ管理します!」とかなると最悪なパフォーマンス低下と招いたりすんのね。
ハッカーでさえこれを嫌ってる。スティーヴ・イエギはこれを次のように紹介している。
ジェイミー・ザウィンスキーが有名なアーティクル"Java Sucks"で書いている。「最初にいい点を挙げると、Javaはfree()する必要がない。その他のことはすべて大したことではないとためらわずに言える。この一点によって、私は他のほとんどあらゆることを、それがいかにひどかろうが許すことができる。この一点によって、この文章にある他のすべてがほとんど些細なことになってしまうのだ」
free()って書くだけなのに間違えるわけだ(笑)。っつーか書き忘れる、か。
こう書いてる、って事はもう頻繁に起こりまくるわけだ。
10年くらい前、いや、もっと前か?ガベージコレクションの是非ってのをまだガンガンやってて。
つまり、「プログラマが責任持ってメモリ管理するのが一番早いんだ」って論調があって(今でもある?)、要はその頃ってまだ「ガベージコレクタ」に対しての信頼度が低かったわけなんだけれども。
でもどこだったかな、なんかの研究の引用のソースで、結局「一般的なプログラマが頑張ってfree()するよりガベージコレクタに任せた方が速いプログラムになる」って結果が出てある程度決着が付いたんじゃないかしらん。
人手に任せるよりプログラムに任せた方が結果安定してるんだ、って事だよな。そりゃそうだ、ガベージコレクタの研究も進んでるわけだし、何より自動化したい、って事こそプログラムを書く理由でもあるわけだ。
自動化出来るモノはガンガン自動化しちまって、人はプログラムに任せられないトコに全力を注げばいい、ってのがある程度真実となる。
当時、尖った人なんかはこういう本読んで面白がってた。
僕は未読だけど、「ガベージコレクション」の色んなやり方を解説してる本との事。
まぁ、いずれにせよ、よっぽどの理由がなければ「ガベージコレクタ」込みのプログラミング言語の方が扱いやすいのは事実だ。
また、安全性の問題もある。要するに想定するメモリ領域を飛び越えて悪さをするプログラムになるか否か、の問題だ。
「安全なプログラムを書こう」とすれば長くなるんだ。あまり本質的じゃないコードが多くなる傾向がある。
なお、上のランキングには含まれてないんだけど、実はANSI Common Lispと言うコンパイラ型言語は(※8)、まぁ、実装にも拠るけれども、ネイティヴコードを吐き出す処理系だと、その生成した実行ファイルはC++が生成した実行ファイルと遜色ないスピードを叩き出す「場合がある」。
そう、「場合がある」んだ。
と言うのも、コードの書き方を工夫して最適化レベルを上げて(※9)、となると「安全なコードを書く為の道具」であるANSI Common Lispのメリットがどんどん無くなっていくわけだ。
Gaucheの実装者、川合史朗さんは次のような事を書いている。
Cの方が機械語に近いのは事実ですが、LispでもほぼC並に速いコードを 書くことは可能です。Lispマシンではなく、現代のアーキテクチャでも。Common Lispの規格の中には最適化オプションの規定もあって、 speedというパラメータを3(最大)にすると、Cで言う-O3みたいな 最適化をやってくれるんですが、さらにsafetyというパラメータを0にして、 型宣言をつけてやれば、多くの処理系は実行時型チェックを省きます。 最適化オプションの指定は コンパイル単位毎だけでなく関数毎にも出来るので、ボトルネックの 関数だけをそのようにコンパイルすることが言語仕様内で可能になっています。 この状態で生成されるコードは、Cで同じロジックを書いてコンパイルした コードにほぼ遜色ありません。〜(中略)〜C並に速いLispコードを書くためには、いくつも気を付けなければならない ことがあります。
- inner loopでメモリをアロケートしない: Cと違ってLispの場合は暗黙のうちに メモリアロケーションが入ることが多いので、どういう操作だとアロケーションが 入らないかを熟知している必要があります。
- 型宣言をつけまくる: あいにく、商用のLispコンパイラでもあまり賢い 型推論は行ってくれないみたいで、とにかく鬼のように型宣言をつけまくる 必要があります。
- safetyを0にすると処理系は救ってくれない:宣言された型とは違う型の オブジェクトを渡すとSEGVしてくれます ;-(
なので、C並に速いLispコードは見た目も安全性もC並になる、というのが 私 (Shiro) の経験です。
「いや、それはANSI Common Lispだからじゃない?」って思うかもしれないけど、違う。
むしろANSI Common Lispが色々出来るんでこういう結果になってる・・・と言うか、実際複数の言語で実験せなアカン辺りをANSI Common Lispなら「横断的に、複数言語で行う実験が一回で済む」って言った方が正しいと思う。なんせ、元々ANSI Common Lispは「書いたソフトのチューニング可」が前提の言語だからだ(※10)。
要は書いたプログラムの「速度」と、「コードの見た目」と「安全性」の間には残念ながらある程度のトレードオフがある、って事だよな。
ベンチマーク的なモノで作ったソフトの「速度」を比較してもそれが全てにはならないし、むしろ実践的な意味では作ったブツのどっかに「危険な落とし穴がある」確率が上がる、ってだけの話になるかもしんない。そして危険を避けようとすればするほど、書いたコードは「分かりづらく」そして「読みづらく」なってくんだ。
もう一度、グリーンスパンの第10法則を紹介しよう。
十分に複雑なCまたはFortranの プログラムは全て、後付けで、正式な仕様がなく、バグがてんこもりの、 遅い、CommonLispの半分の実装を含んでいる
「プログラミング言語の速さランキング」とか盛り上がるネタとしては悪くないだろう。
ただ、「プログラミング言語の速さ」だけにこだわるな。そもそも最初に書いた通り、実は「プログラミング言語の速さ」と言うのは、構文設計的に、書かれたモノがスピードを違えない以上、定義が曖昧だ。
それは「言語」なのか?あるいは「特定実装の最適化技術」なのかい?
ベンチマークを信じるな。「自分が作った実践的なモノ」がそのスピードを保証するものじゃないし、仮に保証してたとしたら、単に「危険な」プログラムを書いただけ、かもしれない。
そして安全なモノを作ろうとしたら結果、「貴方が思ってた」遅いプログラミング言語で書いたモノと大して速度が変わらなくなることさえあり得るんだ。
「プログラミング言語選び」には色んな側面がある。
いずれにせよ、「速さ」だけにこだわるのは間違ってるし、そして自分で言うトコの「速さ」をまずは定義しよう。
と言う話は話で終わっておいて。
参考までに次のような実験をしてみる。
いわゆるHello, worldプログラムだ。
例えばC言語でオーソドックスに書くとこうなるよな。
#include <stdio.h>
#include <stdlib.h>
int main(void) {
puts("Hello, World!");
return EXIT_SUCCESS;
}
Schemeで書くと単にこれだ。
(display "Hello, World!")(newline)
C言語で7行がSchemeだと2行だ。
まぁ、あんま真面目に受け取ってほしくない「比較」なんだけど、7行書かなきゃならないものが2行で済む、ってのはやっぱ「高級言語の旨味」なんだよ。やりたい事がより少ない行数で実現出来れば価値が大きいのね。少なくとも個人開発とかだと効いてくる。
でもこの2種類のコードは「どれくらい圧縮されてる」と思う?
まぁ、一般的にSchemeが「遅い」ってのは正しいとは思う。バイトコードインタプリタが殆どだし。良くてJava程度の実行スピードだろう。
ところが、こういう(権威がないにせよ)「言語仕様書がある言語」だと、実装者が色んな目的を持って性質的に違う実装を作ったりするわけだわ。
んで、中には「SchemeのコードをC言語のコードへとコンパイルする」処理系があったりする(※11)。
ここではGambit Schemeと言う処理系を使ってみてみよう。
上の2つの例はどっちも端末に「Hello, World!」と表示するコードなんだけど、Gambit Schemeで後者のコードをC言語のソースコードへとコンパイルすると何とこのようになるんだ。見た(笑)?
いや、あんまクソ真面目に受け取る必要はないんだけど、あくまで「量としてだけ」考えた場合だぜ?C言語で直書きして7行がScheme -> Cのコンパイラだと163行になってる。「C言語直書き」の23倍だ(笑)。
ホントにクソ真面目に捉える必要はないんだけど、言い換えるとSchemeの2行のコードはC言語での163行に匹敵する「情報量だ」と言う「可能性がある」し、またC言語で本当に「安全なソフトウェアを作ろう」とすればSchemeで1行で済む事を81行書かなかアカン、って事かもしれん。
だからマジメに受け取るなっての(笑)。ただし、安全性とか考えると「最悪それくらい膨れ上がる」覚悟はしといた方がエエかもな、って話だし、逆に言えばSchemeがC言語に比べて「遅い」理由にもなるだろ。誰だって7行で済むトコを「同じ事をするのに」163行書く、って言うのなら156行くらい無駄な事書いてんじゃねぇの、って疑いになる筈だ(笑)。
なお、アセンブリの結果も見てみるか。
最初のC言語直書きの"Hello, World!"はこのようになっている。127行だ。単純に考えると(いや、単純に考え過ぎだが敢えて)、C言語はそれでも127行のアセンブリのコードを1/18の労力で書ける言語だ、と言う事になる。
Schemeの場合はどうか。GambitでC言語へコンパイルしてなおかつ実行形式にコンパイルする。そのアセンブリはこのようになっている。264行だ。
要は同じ事をさせるにせよアセンブリレベルでSchemeはC言語のそれより二倍のコード量を要してる。それだけ「遅い」わけで、なおかつ「安全」って事だな。
もう一回言うけど、「速度」と「安全性」はある種トレードオフの関係なんだ、って事の杜撰な証明だ(※12)。
※1: 何度か言ってるが、例えばJavaで要するJVM(Java仮想マシン)や、C#やF#で要する.NET(と言うかCommon Language Infrastructureか)は原理的にはインタプリタだ。
より正確に言うと、JavaやC#あるいはF#は、書かれたコードを上記の仮想マシン(インタプリタ)で使ってる機械語(これはコンピュータ本体の機械語とは違う)にコンパイルする。このテの「仮想マシン用の機械語」を「中間言語」とか「バイトコード」、等と呼んだりするが、いずれにせよ仮想マシンはその「仮想マシン用の機械語」を一行づつ読みながらコンピュータ本体の機械語に翻訳して実行する。
なお、「仮想マシンだからインタプリタ」なのではなく、何度か言ってるが、コンピュータの動作原理は本質的にはインタプリタだ。
※2: コンピュータ本体の、の意。例えばインテルチップ用のマシン語を指す。
※3: オープンソース系のC言語のコンパイラ実装(例えばGCC、Clang)には仕様で要求されていない末尾再帰最適化の機能がある。Cコードに末尾再帰を発見すると、最適化要求に応じてアセンブリレベルでジャンプ構文に変換してくれる。
反面、MicrosoftのC言語実装だとそういう機能は搭載されていない。これは別にMicrosoftが技術的に劣っているから、と言う理由ではなく、仕様で要求されてない事は無理して実装する必要はないから、だ。
なお、本文では「コンパイラが直接機械語を生成する」ように書いてるが、殆どのケースではアセンブリ言語で書かれたソースファイルへとコンパイルして、アセンブラ(つまり事実上別のソフト)がそれを機械語に変換してる。
※4: Optimization。コンパイラでは「速いマシン語を生成する、コンパイラ自体をプログラムするテクニック」を指す。ここで差が出る為、コンパイラ同士で差が出るわけだ。
※5: 「言語仕様書」と「リファレンス」は全く性質が違うモノだ。
言語仕様書とは、理想論的だが、「そこで解説されてるようにプログラムを組むと、いつの間にやらそのプログラミング言語になっている」類の文書の事で、いわゆる「ユーザーマニュアル」的なモノではない。
また、言語仕様書があるプログラミング言語は、その言語仕様書で要求してる仕様を満たせば「そのプログラミング言語実装」を名のれる。Pythonには言語仕様書がないが、Rubyにはある、ってのはその違いだ。
言い換えるとRubyの動作で不思議なトコがあっても「言語仕様書で解説してるなら」その通り、って事になるが、反面、Pythonには「何故そうなるのか」分からなかったりする事が多い(単に「実装上の都合」で終わる事になる)。
また、言語仕様書には「権威のあるもの」から「無いもの」まであって、ISO/ECMAで制定した仕様書には「権威がある」、または日本国内ではJIS(日本産業規格)で制定した仕様書には「権威がある」が、特定の企業や集団が決めた仕様書が「権威があるか」と言われるとそりゃないだろ、って話になる。
例えばCの仕様変更は何人もが集った「委員会」で決定されるが、JavaはOracleの都合でどうにでもなる、って事だ(「民主的」が必ずしもいつも良い結果を生むかどうかはさておいて)。
また、「権威がない仕様書」の場合、仕様書に従わない部分が出てきても「その言語名を名乗る」事がありえて、結果、仕様書の制定理由、「各処理系同士の互換性」に難がある、って事が出てきて意味が薄まるわけだ。
※6: だからこれを言っちゃうと心苦しいんだけど、「理論的には」Lispなんざを選んじゃダメなんだ(笑)。いや、俺がそれを好きかどうか、ってのは関係なく、正直者としては言っておかないとならない(笑)。何故なら「Lispには標準が存在しないから」だ。
Lispを選ぶリスクはプログラミング言語としてPythonを選ぶのと同程度のリスクがある、とは言っておこう。言い換えると、Pythonのリスクに対して「関係ねーな」って思える人にはLispも大したリスクにはならん、っつー事だ。
ちなみに、ここで「う〜ん」と悩む人は、ISO/JISで制定されてるプログラミング言語、別名Acceptable Lisp(やMatzLisp)と呼ばれるRubyを選ぶだろう。
※7: このランキング内では、Julia、Java、C#、F#の4つがガベージコレクタ付きの言語で、往年の「ガベージコレクタ付きの言語で作ったソフトは遅い」と言う印象に反して、ランキングの殆ど1/2がガベージコレクタ付きになってる。結果、「ガベージコレクタを使えば遅い」と言うのは印象論なんだ。
これも当然で、技術は日進月歩なんで、「かつて遅かった」は「今遅い」を意味しない。
また、Lisp、Python、Rubyなんかのモダンな言語処理系も全てガベージコレクタを抱えている。
※8: ANSI Common Lispはプログラミング言語としては珍しく「言語仕様書にコンパイラが定義されて」いて、しかも仕様の要求には「インタプリタであるべき」とは書かれていない。
言い換えると、ANSI Common Lispが、アメリカ国内限定だとしても、珍しく「コンパイラであるべき」と指定された、唯一の「コンパイラ型言語」だ。
※9: 最適化レベルとは、どの辺までの速さの実行ファイルを生成するか、の事で、通常コンパイラは最適化レベルを指定出来る。
何でこんな機能があるのか、と言うと、最適化レベルを上げれば上げる程確かに実行スピードは速くはなるが、可搬性が落ちる事になるから、だ。例えば貴方が作ったソフトウェアが貴方の使ってるPCに最適化「しすぎた」場合、友だちにそれをあげても友だちのPCでは「動かない」と言う事がまま生じる・・・CPU回りが全部同じと言う保証がねぇからな。
なお、Linuxディストロの一つであるGentooがDebian系LinuxやRedHat系Linuxディストロのように「バイナリでのリポジトリ」を提供していないのは、ある意味、そのテの「最適化マニアの為のディストロ」なんで、全てがソースコードベースのインストールで、自分の使ってるPC用に最適化した「超高速な」ソフトウェアで遊べるようしてるからだ。
※10: 往年のLisperにはC言語どころかアセンブリバリバリのブリバリのバリブリのブリブリって人が山ほどいたらしく、Lispのコードを書きながら「どういうアセンブリコードを吐き出すか」リアルタイムで考える人とか、実際吐き出された実行ファイルをディスアセンブルしながら最適化して高速化する、と言うようなワケの分からん人間が腐る程いたらしい(笑)。
だからこそLispは「ハッカーのおもちゃ」だったわけで、そういう人達の要求がANSI Common Lispにはたくさん詰まってるわけだ。
だから言語仕様に逆アセンブラが入ってる、と言う異常っぷりである(そんなモン、フツーは無い・笑)。
ANSI Common Lisperは自分が書いたコードをディスアセンブルして出て来たアセンブリコードを眺めながら「う〜ん、ここはもうちょっと最適化して速く出来るかな?」とか今日もやってるわけだ(笑)。
※11: 1980年代のGNU Common Lisp(当時はKyoto Common Lisp)の登場以降、割にオーソドックスなテで、中間言語としてC言語へのソースコードへコンパイルして、それからC言語コンパイラでそれをコンパイルする処理系がある。
※12: ホント杜撰すぎる話だけど意図は伝わるとは思う。
実際はScheme版だと通常、Runtimeがあったり何だ、で、生成するCコードの量やアセンブリの量はここでの比較より遥かに多いくらいだろう。
だから「Schemeは速度的に不利だ」ってのは当然で、またそれだけセキュアな事を裏で色々やってる、ってこった。
そしてもう一度書くけど、「速度で優秀な筈のCで」セキュアに書こうとすると、ここで自動生成したコードの「量」を遥かに凌ぐ可能性がある、ってこった。まぁ、"Hello, World!"って表示するだけにセキュアもクソもねぇけど、色んな局面でボトルネックとして効いてくる、って話だな。
ちなみに、何でこういうScheme->Cコンパイラを入手する、って事を考えたのか、と言うと、教えて!gooの方で「C言語の宿題丸投げ」があんまりにも多いので、Schemeで回答書いてそれをCのソースへ翻訳したヤツを投下すりゃあエエんちゃうの?って一時期悪い事を考えてたから、だ(笑)。
どうせ宿題丸投げ組はソースコードなんざ読んで勉強する気もねぇんだし、「コンパイラが自動生成したコードでも構わんだろ」ってぇんで色々と実験してみたんだが、あまり上手く行かない(っつーか生成ファイルが多すぎる・笑)んで頓挫した、って経緯があったわけだ(笑)。