見出し画像

Retro-gaming and so on

RE: プログラミング学習日記 2022/10/29〜

星田さんの記事に対するコメント。

木構造の出力はラベル版が良いけど入力はレコード版が楽な印象

そうそう、それぞれにメリット・デメリットがある。
随時、場合によって使い分けよう。

 これらをキーワードにしてアマゾンで検索しても規格対応とかって明示されてないんですよねぇ(僕もC言語規格に色々とあるとか知らんかったし)。

うん、まず別にC言語の規格に色々あるわけじゃない。
この辺、別に星田さんを責めてるワケじゃなくって、現実的な問題として殆どのC言語ユーザーが実は知らなかったりする話、だ。
と言うか、C言語脳は自分が一体何を使ってるのか正確には把握していない
その前に、一度、あるいはもう一回、権威ある仕様がどこが決めてるのか、整理してみる。
前提として、権威ある仕様が制定したプログラミング言語、と言うのは、その仕様を満たさない場合、そのプログラミング言語処理系、として名乗れない。これが大原則だ。

「いやだ、権威主義だなんて!」

とか思うかもしんない(笑)。しかしこれには理由がある。
要するに、例えば70年代とか80年代に、あるプログラミング言語が「良い」となって、A社とB社がそのプログラミング言語を採用した実装をそれぞれ個別に開発して発売した、とする。
C君はA社の処理系を買った、クラスメートのDさん(美少女)がB社の処理系を買った、としよう。C君はスラスラとA社の処理系でプログラムを書ける。一方、Dさん(美少女)はあまりプログラミングが得意じゃない。出来ないわけじゃないけど、プログラミングに苦戦してる。

「あれ、Dさん(美少女)も"あるプログラミング言語"を使ってるんでしょ?僕のソースコードをあげるよ。そうしたら動くはずさ。」

と、C君は「今後優しくしていけばDさん(美少女)とベッドイン出来るかもしんない。うししし。」と下心丸出しで、Dさんが苦戦してるプログラミングを助ける事にした。
ところがC君に提供して貰ったソースコードはDさんの処理系では全く動かずエラーを出しまくる。

「もう!Cのヤツ!ウソばっか!全然これ、動かないじゃない!」

とお冠だ。
結果C君のDさん(美少女)とのベッドイン計画は儚くも崩れ去るのであった・・・・・・。

つまり、70年代〜80年代にかけて、こういう「美少女とのベッドイン」を果たせないヤツが山ほど出たわけだ(笑・※1)。一番有名なのがご存知BASICだ。
そう、覚えてるだろ?PC-6001もPC-6601もPC-8001もPC-8801もPC-9801もApple IIもCommodore 64も富士通 FM-7も富士通FM-8もSHARP X1もSHARP MZも全部BASICを搭載してた筈だ。ところが、どういうわけか、ベーマガに掲載されたある機種用のプログラムを自分が持ってる別の機種で動かそうとすると上手く動かない。互換性に難がある、ってのを経験した筈だ。
つまり、全部BASICって名前が付いてたにも関わらず、事実上違ったわけだよな。いや、被ってる部分もあるんだけど、要するに「何が同じで何が違うのか」ハッキリしてないわけだ。
この互換性の問題を解決する為に公式仕様と言うモノの制定の必要性、ってのが出てきたんだよ。「少なくともこういう動作で、最低限こういう関数だけは用意して欲しい」と言うガイドラインが要求されたわけだ(※2)。
従って、公式仕様は権威がないとならない。この仕様を満たさないモノはその言語の名前を名乗っちゃいけない、ってくらいじゃないと「全員がどの処理系だろうと安心して使える」保証にはならないから、だ。
これが権威ある仕様が望まれた背景なんだ。

さて、じゃあ権威ある仕様はどこが決めてるんだろうか?
ぶっちゃけると、まずドメスティック(ある国の中)だと国にかなり近い機関が決めている。
アメリカ国内だと次の2つが有名だろう。

  • ANSI(米国国家規格協会)
  • IEEE(米国電気電子学会)
この2つはThe United States of Americaと言う「国家の」組織ではないが、近い位置にはいる。また、後者は「仕様制定機関」と言うより学術団体に近い。ただし、やっぱたまにプログラミング言語の公式仕様を制定する。
日本国内ではご存知JISだ。

こっちはホンマモンの国家規格だ。国家権力だ。親方日の丸だ。
いずれにせよ、「ある国の中」で産業の発展の為には共通基盤が無けりゃ駄目だろ、と言う発想の下で仕様が制定されている。そしてその仕様に従う限り、その国内の産業内では混乱が起きないだろ、と言うワケだ(※3)。
ところが、主に1990年代、今度は国際間で「標準」をどーするか、って話に広がっていったわけだな。それまではある国Aと別の国Bで「違っていても」構わなかったケースが多かったんだけど、経済の発展によりそれだけじゃダメだろ、って気運が高まってきたわけだ。
もちろん、国際標準、ってのを考える組織は以前からあったんだけど、そこでの仕事の範囲が今度は「国家間でのプログラミング言語の標準化」まで広がってきたわけだ。
そこで出てくるのが

の2つだ。
んで、必ずしも実は必要ではないんだけど、現在ではドメスティックな標準化機関は、ISOないしはECMAと互換性がある仕様を国内で通じる仕様、としてるケースが多い。例えば、いわゆるJavaScript(正式名称はECMAScript)のJISでの仕様は「ECMA仕様書を参照して下さい」としか書いてない(笑)。国家的な丸投げだ(笑)。

そしてもう一つ重要な事がある。プログラミング言語の改訂だ。
原則、仕様が改訂された場合、常に最新の仕様が新しいスタンダードだ。
これは当然だろ。そもそも古い仕様で充分だったら新しい仕様は必要がない、って事になる。
なんでわざわざ労力を払って「古い仕様で充分」だったものを改訂する必要があるんだ?もしそんなバカな事が起き得るんだったら、プログラミング言語の仕様策定者たちはとんでもない馬鹿野郎共の集まり、って事になる。仕様を変更する事を仕事にする為に仕様を変更し続けるのか?
んなアホな。
つまり、仕様の改訂、ってのは常にそのプログラミング言語でよりラクなプログラミングが行えるように改訂されるわけだ。これを肝に銘じよう。
そして旧仕様はあくまで「参考の」と言う立ち位置に下がる。
あるいはどうしても事情があって・・・と言う特殊な実装の場合は、販売やマニュアルに「(過去の仕様に)準じてます」って記載するのがマナーだ。
これが原則だ。

従って、国際的な意味に於いて、現在「C言語」と言えば何を指すか、自ずとから知れるだろう。通称C17しかあり得ない、んだ。
これ、マジで、「ANSI と言う仕様があり、C99と言う仕様があり・・・」とかのたまうヤツが多いんだけど、ハッキリ言ってやる。
国際的にはC言語と言うのは現時点C17を指すそれ以外の仕様は存在しない
単純な話だろ?仕様は常に新しいものが優先される、そして「C言語でプログラミングをますますラクになるように仕様改訂されてる」って原則を見れば当然の帰結なんだよ。
まずそこを原点として押さえる事。

ただし、ここからC特有の厄介な話が入り込んでくるわけだ。補足事項が出てくるわけ。
まず、今更ANSI Cが標準、なんつー事を言うヤツは無視していい。こういうのは「何が標準なのか」って言うのを知らないだけだ。
こういう輩は放っといて、Cにまつわる問題点は大まかに言うと二点ある。

  • 日本国内の「C言語」仕様と国際標準の「C言語」の間にズレが出てしまった。
  • Microsoftが長い間、C言語処理系を仕様に従って全くアップデートしなかった。
そう、まず日本国内に於いて、「C言語の仕様」ってのは1999年に制定されたC99以降全く仕様改訂されてない、んだ。
そういう意味で言うと、日本ではまるで仕様が2つ存在するように見える。

  • JISで制定されてる「C言語」。ISOで制定されたC99互換
  • 国際的な標準であるC17
しかしながら、今までの議論に関して言うと分かるだろう。いまだ日本ではC言語とはC99の事なんだ。JISが国家規格である以上、そう言った話になる。
そしていくらISOがあろうと、C17は日本国内ではC言語ではない。もちろん、「敢えて」ISO標準ですよ、って宣言を妨げる事にはならんが、基本的に日本国内ではJIS規格が優先される、って考えていいだろう。
例えば、「国内規格」って事を考えると、政府が何らかのプログラムを発注するとして、「C言語で書く」って選択になるとそれはJIS規格のC言語を使う事になる。つまりC99で書かなければならない、ってのが原則だ。
ましてやJISで制定されてない言語は、公的な意味に於いては、後方互換性を考慮すると使えない、って事だ(※4)。
いずれにせよ、何が原因だかは分からないが、JISではこの20年間、C言語を改訂する、って事はしてないし、ISOと足並みを揃えよう、と言う動きがない。

もう一つの問題点が、端的に言うと「MS-DOSからWindowsに至るまで、長い間Microsoft実装がC言語の仕様にcatch-upしてこなかった」と言う事が挙げられる。要するに、例えば初心者がC言語を扱うにしても、MS-DOS/Windowsで比較的簡単に扱えるC言語実装がVisual C++に付属してるブツしかなかった、って事だ。
これも分かるだろう。いくら仕様が改訂されようと、「使える実装」が無いと人々はそれを使おうとはしない。JIS ISLISPと同じような状態だったわけだ。
MicrosoftがVisual C++の初版をリリースしたのが、日本では、ほぼ万人がPCを「初めて買う」経験をしたWindows95登場以前の1993年前後だ。そしてこの時点ではC言語の規格はANSI C/ISO C90だった。そしてこれ以降、原則的にMicrosoftはC++に対しては比較的公的仕様に準じてアップデートするようにして追従してはいるが、Cに関しては据え置きの状態が長く続いてた。
これも理由はハッキリしてるだろう。MicrosoftはC++推しだけどCはそれほど重要視してなかった、って事だ。なんせWindowsの開発ツール自体がC++だったし、GUIのソフトウェアを作る以上、Apple Macintosh以来、オブジェクト指向は必須、だと思われている(そもそも、理論的には、Windowシステム自体がオブジェクト指向で言う「継承」で作られている・※5)。
特に初心者に対しては、例えば大学なんかの「Microsoft嫌い」の教員でも、GNUのGCCなんかを薦めるワケにはなかなかイカない。代わりに旧ボーランドのCコンパイラのフリー版(通称BCC)なんかを推奨してたりしてたわけだが、生憎フリー版、っつー事はそれ以上アップデートするわけでもない。
従って、長い間、「C言語を学ぶ」と言うのは「ANSI Cを学ぶ」しか無かったんだ。
このように、1999年にJISがC言語の仕様をISO C99と互換、としても「手軽に使える処理系が全くWindowsに存在しない」って状態が長く続いたんだな。
もちろん、好事家なプログラマやら、仕様をマジメに考える人はLinux等のフリーOSを入手して、Microsoft実装じゃない、ハッキリ言えばGNUのGCCで「規格に準じた」C言語を使おう、とはしただろう。しかし、結局それは一部の人でしかないわけだ。限りなくハッカーに近い層だけ、が「本当のC言語を使う」って状況になっていたわけ。それが25年以上は続いたんだ。
いずれにせよ、事実上、JISのC言語に合わない古い規格でC言語でのプログラミングを行わなければならなかったわけ(※6)。
そして、2017年以降、久々にMicrosoftはC言語をC17に追従するようにアップデートした。
しかしながら今度はC17は日本国内ではC言語ではないと言うワケの分からん状態になっている(笑)。
いずれにせよ、フツーのWindowsだと日本じゃ日本公式のC言語を学べないと言うワケだ(笑)。
はい、これホントの話(笑)。だからC言語を学習する事を尚更薦めねぇんだよ(笑)。
来年ISOではC23が発表されるらしいんだけど、一体どうなる事やら(笑)。

となると、ここは英語からの翻訳、それもオライリーかな?ということで調べると牛の表紙のがあったんだけどC99で古いという意見もある模様。

多分それが正解だ。
何故なら今まで書いた通り、どっちにせよ日本でのC言語の公式規格/仕様はISO C99だから、だ。
だから何をもって「古い」って言ってるんだかサッパリなんだけど、少なくとも日本オンリーの話をすれば、「それは公的に通用する事が書かれている書籍だ」って事になる。
逆にC17を学んでも、国際的には「C言語を学んだ」事にはなるけど、日本限定の話をすれば「C言語を学んだ」事には残念ながらならない、んだ。

日本人作者なんですがこういう表記があったので(^_^;)

うん、ごめん、こないだ3冊の話を遡上にあげたんだけど、事実上その本も古い規格に合わせて書かれてると思うわ。
っつーか、C99やC17で書かれたC言語のプログラミング入門書の類を全く知らない(笑)。無い、って言ってイイと思う。
最悪な事に、例えば本の帯にC99対応、とかC17対応、って書かれていてもC言語のプログラミング入門書の場合、アテになんない
何故なら、ISOのC言語策定委員会はバックワードコンパティビリティ(後方互換性)に神経使って仕様を決定してるから、だ。すなわち、古いANSI Cの書き方でも受け入れるように設計してんだよ。そしてそれは新仕様では必ずしも望ましいスタイルじゃあないんだ(※7)。
んで、結局、大方のC言語入門書は、C言語へのNew Comerに「古いスタイルを強要する」、一種パワハラ染みた本になってんのね。若者をマウンティングする為の老害本と言って良い。
だからあんまマジメにC言語を勉強しちゃあダメなんだ。教養に留めておくべきだ、本気になんな、って言ってるのは実はそういう理由なの。

なお、ある程度本気でC言語(C99)を学びたいって言った場合・・・いや、後で様子見して教えようかしらん、とかちと思ってたんだけど。
英語のサイトで良ければこういうサイトがある。


題名通り、1,000行以下でC言語(C99)でLispを書こうぜ、ってサイトだ(爆
これ、マジな話、「C言語を一回も触ったことがない人」向けに書かれてるんで、驚いた。そして、英語の入門サイトでも実の事言うと、通常、全部ANSI Cで書かれてたりするんだけど、このサイト「だけ」はC99が使われてるんで二度ビックリだった。
川合史朗さんによると、かつての同僚が書いてる、って話だ(※8)。
実際、フツーはK&Rを元にした本ばっかだし、マジに「実際に使えるプログラムを書きながら」C言語を教えよう、なんつーサイト/書籍は皆無なんで、非常に良いサイト、です(しかも危ないscanfなんぞ使わんし)。ある意味、昔で言う「ゲーム書きながらBASICを学ぼう」って言うノリに極めて近い(まぁ、Lispって言語に興味があるか無いか、って話はどうしてもついて回るが・苦笑)。
ただし、要GCCと言う条件はある。

※1: もちろんこれは作り話だ(笑)。
第一に、70年代〜80年代は殆どの女の子はプログラミングなんざキョーミがなかった。
第二に、美少女はプログラミングなんざしない。プログラミングにキョーミがあるような女はブ(以下自主規制

なお、プログラムのソースコードには著作権が生じるが、作られたプログラミング言語には著作権は適用されないらしい(と言うのも、じゃあ、そのプログラミング言語で書かれたプログラムの著作権はどうなるんだ、とかややこしい問題が絡んでくる)。
よって「ある実装の動作を真似て別の実装を作る」って事はあり得るんだけど、それでも「文書としての公式仕様」が無いと細かいトコで違いが出て大変な事になる。
誰も覚えてねぇだろうけど、Microsoftが「仕様の無い」Javaの互換の実装、J++とかJ#ってのを出してた事があるんだが、結果色々と上手く無かったのか、消えてしまった。
なお、実のトコ、現時点でも、Oracleの公的なJavaの他にOpenJDKと言う実装があり、結果この世にはJava実装が最低でも二つ現存してる、って事になるが、後者はJavaの開発元であるSun Microsystemsによって始められた為、そりゃMicrosoftが外部で頑張ったよりはマシになって当然、マシにならなきゃ困ったちゃん、だ。
いずれにせよ、「仕様がない言語」と言うのは互換実装を作るのは大変なんだ。

※2: 何度か書くが「最低限」だ。
言い換えると、言語ベンダーが「自社処理系に独自の関数を追加する」とか「独自拡張を施す」事を妨げる事はない。
「最低限公式仕様を満たして」なおかつ他に欲しい、と言った場合は改良するのは悪い事じゃないんだ。

※3: このブログで、単にCommon Lispと書かずに、ANSI Common Lispと書いてるのはこれが理由だ。日本国内に於いてはANSI Common Lispは標準でも何でもない。従って名前に反してCommonでもない。あくまでアメリカローカルでの、アメリカだけで通じる公式仕様、だと言外に言っている。
んで、こういう事を書くと、「世界でCommon Lispは標準的に使われてて・・・」と難癖を付けるヤツが絶対現れるんだが、デファクトスタンダードとスタンダードは意味が違う、んだ。前提が何か、ってのを確認しないのは、実の事を言うとC言語脳だけ、じゃなくってLisperにも見られる傾向だ。
「現実的にANSI Common Lispが標準と見做されている」と言うのと「ANSI Common Lispが世界標準である」と言うのは意味が違う、んだ。理論的に考えろ
そして更に言うと「Schemeには標準が無い」(何故なら権威ある仕様がないから)と攻撃するCL使いの輩もいるが、言っちゃえばCommon Lispも標準じゃない、んだ。
ぶっちゃけ、個人的には、こういう事が分かった時、「目糞鼻糞だな」とか思った。
そして残念ながら、Lispには標準がいまだ存在しない。より正確には国際標準であるISLISPがあるけど、実装の存在率が0に近い、ってぇんで使いもんにならん、っつーのも毎回言ってる話だ。

※4: 実は理想論、だ(笑)。
現実問題、公的組織、例えば行政やら、県庁以下の役所なんかの発注では「(JISの公的仕様に含まれない)Visual Basic」なんかでのプログラミングが多いそうだ(笑)。
ぶっちゃけた話、発注側の公的組織自体が「JIS規格が一体何の為にあるのか」良く分かってないわけで(笑)、ツール類は当然、Microsoftの寡占状態になってるのが実態だ。
これは、役所関連が全くIT関係の事を良く分かってない、と言う例でもあり、日本が何故にIT後進国なのか、と言う理由の1つでもある。政治・行政がホント「良く分かってない」わけだ。
ちなみに、あくまで「理論的な話」ではあるが、仮に行政等が「何の為にJIS規格があるのか」理解した場合、そこから請ける受注では、当然「Schemeでプログラミングしたり」「ANSI Common Lispでプログラミングしたり」「Pythonでプログラミングしたり」は出来ない。国等の公的機関で必要なモノを作るプログラミング言語がJISで仕様を保証してない以上、将来的に後方互換性が危ういわけで、当然「使えない」と言う判断になる。
一方、JIS規格があるRubyで受注するのは正攻法だ、と言う事になる。

※5: 旧Apple MacintoshのOSを書いたプログラミング言語は、オブジェクト指向をくっつけたPascal、Object Pascalだ。これはMacintoshでのAppleからの推奨アプリケーション開発用プログラミング言語でもあった。
なお、C++に続き、Object PascalもISOに承認されるように動いたらしいが、残念ながらObject Pascal、と言う公的仕様は否決となったらしい。
ちなみに、Pascal自体はISO規格が存在し、それ以前にあった「Pascal言語の実装同士による非互換性」の問題を一応解決はしてる。
また、エンバカデロ・テクノロジーズ(旧ボーランド)が発売してるDelphiと言うプログラミング言語は、結果Pascalの方言だ。そしてオープンソースのFree Pascalと言う実装は、Pascalそのもの、と言うよりDelphi互換を目指してるプログラミング言語だ(若干バギーだが)。

※6: なお、1998年に、実はminGWと言うLinuxのGCCをWindowsに移植したコンパイラが出ている。
これはアップデートされてるし、WindowsでのCコンパイラとしては福音的な存在だ。
しかし、ぶっちゃけて言うと通のあなたが思うほどWindowsでは知名度がないんだわ(笑)。2022年現在でも、minGWを知ってるのは通、って言って良い。
従って、悲しい事に、最初からminGW使ってCプログラミングを学びました、って初心者はほぼいない。

※7: ちなみに、C99以前とC99以降の、例えば大きな違いは、変数宣言部、と言うのが消えた事だ。
例えば、C99以降は次のように書くのは悪いスタイルだ。


このように書くべき、ってのがC99以降では示唆されている。



色々と違いはあるが、ここでは、大まかに、C言語にはプログラムや関数の冒頭には変数宣言部なぞ存在しない、と言う事を指摘しておく。
PythonやLispだとそもそも動的型付け言語なんで変数宣言が存在しないが、いずれにせよ、変数を使いたい時にその直前で宣言をする、ってのがC99以降だと望まれるスタイルになる。何故ならその方が明解だから、だ。
この辺を頑固にANSI Cスタイルで書いて伝授せねばならない、ってのは単純に言って老害以外の何物でもない。まずは仕様書を読め、と言いたい。
また、安直なscanf使用とかも害悪だ。安全に使おうとすればクソややこしくなる
return 0;とかreturn (0);なんて書くのも害悪だ。明解にreturn EXIT_SUCCESS;とすべきだし、真偽値も1と0じゃなくって#include <stdbool.h>してtruefalseを使うべきだ。
とにかくC言語は俺が長年こう書いてきたんだからこうしろってのが多すぎるんだわ。ここにもプログラマ特有の「俺が」が顔を出す。
もちろん、自分で書く時、どう書くか決めるのは自分自身だからその辺はどーでも良い。
問題はそれは人に教えるモンじゃねーだろ、って事を言っているんだ。
だからC言語そのものの教育環境がグチャグチャだ、って言ってるわけだ。

なお、Algol辺りから出てきた古典的プログラミング言語の「書き方の設計」として、プログラムのアタマから

  1. ラベル宣言部
  2. 定数定義部
  3. 型定義部
  4. 変数宣言部
と書いてから、やっと関数本体を書き出す、と言うのが様式になってて、実は最初のCが設計された時は、この影響下にあった。
元々こういう「☓☓の場所には△△がある」と言う「設計」は、恐らくソースファイルをワンパス(つまり一回走査するだけで)でコンパイルする為のトリックだろう。コンパイラの都合に合わせた設計だったわけだ。
ところがどっこい、プリプロセッサを含むC言語は当初からワンパスではコンパイル出来ない言語で、マルチパス(つまり複数回ファイルを走査する)じゃないとコンパイル出来ないわけだ。
つまり、こういうAlgol風の「言語デザイン」が全く無駄だ、と気づいたのがGNUで、ANSI C/ISO C90が制定されてから割に早い時期に、C言語で「変数宣言はプログラム/関数冒頭じゃなくても構わない」とコンパイラを拡張、結果その「GNUの独自拡張」がC99に取り入れられて、Algolの「悪しき」影響から解き放たれたわけだ。
それを鑑みてみても、C99から20年以上も経ってるのに「変数宣言はプログラム/関数冒頭に」って書いてるヤツはアタマがおかしいと思っている。

※8: ちなみに、この人が某巨大匿名掲示板で一時期話題になったGCCの拡張ライブラリ、Celloの作者だ。Build your own Lispなんつーサイトを作るくらいなんで、Lispを始めとした関数型言語に詳しく、Cの拡張でCの中で関数型言語っぽいプログラムを書けるようにしてくれた人。そしてその使い勝手はC++のテンプレートより上なんじゃないか。
惜しむらくは、Cello独特のデータ型にまつわる表記法の「異様さ」なんだけど、一方、GLIBのクッソなげぇ表記に慣れてるCハッカーにとっては、大した表記法でもないんだろう。
ただし、GCC及びC99のヘビーユーザーらしく、他のコンパイラや他の仕様で使えるような可搬性のあるライブラリにはなっていない。
  • Xでシェアする
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

最近の「RE: プログラミング学習日記」カテゴリーもっと見る

最近の記事
バックナンバー
人気記事