アカウント名:
パスワード:
C#に置き換わり、C++は廃れてしまったりするのでしょうか
そんなことないと信じています。 というか、C#ってC++
30年どころか、100年たっても間違いなく生き残るであろう言語が少なくとも2つはあるでしょう。アセンブラとCです。
これらの言語の特異な点は、言語のsemanticsに面倒な実行時の支援処理や初期化が一切含まれていないことです。すなわち、自分で作ったエントリポイントにいきなり処理を飛ばしてもきちんと動作するわけです。これは計算機をbootさせるためには
プログラムは全てユーザプロセスとして動くものばかりではありませんよ。あるOSの元でプログラムが動くと勝手に仮定すると、Cの重要な本質を見失ってしまいます。
一般的なコンパイラ出力の C 処理系のみを考えても、スタートアップコードを必要とします。これは C 以外のもので書かれていますよね。
私はとあるRISCの評価中、IPLのためのload addressとentry addressだけをheaderとしてつけたC言語のプログラムを組んだことがあります。cross compilerゆえlibraryどころかstartupすら使えませんでし
brake-handle さんの書いたコードが実行される前に、フレームポインタやスタックポインタをセットする(スタートアップの代わりを果たす)コードがあったはずですが、、、
stack pointerの更新にinline assemblerを使えば、残りの部分はCで書くことができます。特にmemory mapped I/Oの場合はそうです。この場合、ROMにCで作ったcodeを焼き、Cの関数をCPUの初期program counterに合わせることすら可能になります。
実用上の問題ない話ですが、C では書けないプログラムがあります。メモリアドレス番値 0 に対するメモリアクセスです。
0を使うのもあくまでlibraryの都合です。別に言語仕様がaccessを禁止しているわけではありません(DOSのころは割込ベクタを直接書き換えるために0番地をaccessしていた)。お望みなら、0xffffffffを使ったっていいんです。ただ、それだとaddress spaceの大きさによって値が変わってしまうことや、一部のRISCではalignment errorを起こすために0を選んだのです。
一見言語仕様に思えるこの実装は、実はエラーの早期発見のためにOSがやっていることなのです(pagingが可能な場合)。
0を使うのもあくまでlibraryの都合です。別に言語仕様がaccessを禁止しているわけではあり ません(DOSのころは割込ベクタを直接書き換えるために0番地をaccessしていた)。お望み なら、0xffffffffを使ったっていいんです。ただ、それだとaddress spaceの大きさによって値が 変わってしまうことや、一部のRISCではalignment errorを起こすために0を選んだのです。
評価結果が 0 になる整数定数式、または void * 型にキャストされた式は、NULL ポインタと呼ばれるポインタに変換されます。 このポインタは、有効なオブジェクトや関数を指すいかなるポインタと比較しても、等しくならないことが保証されていま す。
Cが今まで生き延びてきた、そしてこれからも生き延びていけるであろう本質 は、後から追加が必要になった機能を全てlibraryに押し込めることができるた めです。決して新しい機能のために言語の文法や意味論に手を加え、それゆ えに過去のsourceを捨ててしまうようなことをしなかったのが強く効いています。
alloca、va_arg/va_start/va_end、setjmp/longjmp のように(ライブラリのみでは実装できないので)言語仕様に入れておいてくれよと言いたくなるような機能
意味がよく分かりません。libraryに欠けている機能は何ですか? 言語仕様に入れるべき理由は?
手元にあるFreeBSDのlibcは、allocaもsetjmp/longjmpも実装しています。libraryにしてはいけない理由は見当たりません。同様に、gccだってva_*をきちんと実装しています。
全体に対する感想なぞありません。VBで生成したcodeをUnixの元で走らせることに成功したのですか? 現実にやっていないことを話してもらっては困ります。
強いて挙げるとすれば、あなたはOSの束縛から逃れることができていないのでしょう。だから私が一切持ち出していないにもかかわらずあなたはOSのABIの話をしたのです。この時点で残りを読む気が全て失せました。
/* alloca_test.c */ /* Compile: gcc -S -O0 alloca_test.s #include <stdio.h> #include <alloca.h> void foo(){ char* p = (char*)alloca(100); }
私はとあるRISCの評価中、IPLのためのload addressとentry addressだけをheaderとしてつけたC言語のプログラムを組んだことがあります。cross compilerゆえlibraryどころかstartupすら使えませんでした。それでもmain()をいきなりentry addressとしてきちんと動作しているんです。
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
海軍に入るくらいなら海賊になった方がいい -- Steven Paul Jobs
ISOってなんか意味あるの? (スコア:2, 興味深い)
よく分からないのですが、今のところ.NETフレームワーク以外に使用されるようなことはなさそうですし、標準でなくていいからMSのほうで勝手にやっていてくれという感じです。
ちなみに、
そんなことないと信じています。
というか、C#ってC++
// Give me chocolates!
Re:ISOってなんか意味あるの? (スコア:1)
ISOになると、各国政府がある程度の後押しをすることになってます。
例えば、おそらくJISにもなるでしょうし、情報処理技術者試験の
選択科目にもなるかもしれません。さらにひょっとしたら、中学や
高校の授業でとりあげられるかもしれません。
今すぐの影響は
100年たっても生き残る言語 (スコア:3, 興味深い)
30年どころか、100年たっても間違いなく生き残るであろう言語が少なくとも2つはあるでしょう。アセンブラとCです。
これらの言語の特異な点は、言語のsemanticsに面倒な実行時の支援処理や初期化が一切含まれていないことです。すなわち、自分で作ったエントリポイントにいきなり処理を飛ばしてもきちんと動作するわけです。これは計算機をbootさせるためには
Re:100年たっても生き残る言語 (スコア:2, 参考になる)
言語の semantics を考えるときは、その言語の色々な実装(例えば C言語だったら
C インタプリタ)でその話が成り立つかどうかを考えるべきです。
> これらの言語の特異な点は、言語のsemanticsに面倒な実行時の支援処理や初期化が
> 一切含まれていないことです。すなわち、自分で作ったエントリポイントにいきなり
> 処理を飛ばしてもきちんと動作するわけです。これは計算機をbootさせるためには必
> ず通らなければならない関門であり、ほかの言語にはマネができません。どんなにプ
> ログラムが組
コンタミは発見の母
Re:100年たっても生き残る言語 (スコア:1)
プログラムは全てユーザプロセスとして動くものばかりではありませんよ。あるOSの元でプログラムが動くと勝手に仮定すると、Cの重要な本質を見失ってしまいます。
私はとあるRISCの評価中、IPLのためのload addressとentry addressだけをheaderとしてつけたC言語のプログラムを組んだことがあります。cross compilerゆえlibraryどころかstartupすら使えませんでし
Re:100年たっても生き残る言語 (スコア:1)
> c言語のプログラムを組んだことがあります。cross compilerゆえlibraryどころかstartupすら
> 使えませんでした。それでもmain()をいきなりentry addressとしてきちんと動作しているんです。
> なので、上述の命題は誤りです。
brake-handle さんの書いたコードが実行される前に、フレームポインタやスタックポインタを
セットする(スタートアップの代わりを果たす)コードがあったはずですが、、、
> osの設計を変えてもcできちんと動作するプログラムが存在
コンタミは発見の母
Re:100年たっても生き残る言語 (スコア:1)
stack pointerの更新にinline assemblerを使えば、残りの部分はCで書くことができます。特にmemory mapped I/Oの場合はそうです。この場合、ROMにCで作ったcodeを焼き、Cの関数をCPUの初期program counterに合わせることすら可能になります。
0を使うのもあくまでlibraryの都合です。別に言語仕様がaccessを禁止しているわけではありません(DOSのころは割込ベクタを直接書き換えるために0番地をaccessしていた)。お望みなら、0xffffffffを使ったっていいんです。ただ、それだとaddress spaceの大きさによって値が変わってしまうことや、一部のRISCではalignment errorを起こすために0を選んだのです。
一見言語仕様に思えるこの実装は、実はエラーの早期発見のためにOSがやっていることなのです(pagingが可能な場合)。
ナルポインタ (スコア:1)
歴史的経緯はおいておくと、 以下のことは言語仕様によって決まっています。
ちょっと手元に K&R がないので MSDN ライブラリの「NULLポインタ」の項目を引かせてもらいます(ただし、C++の説明と混じっています)。
というわけで、演算結果であろうと 0 になったものはヌル。 ヌルの先に有るのは有効なオブジェクトではないので、 その先へのアクセスは正常ではありません。
これは未定義です。
p = 0; とやった時、p の指すレジスタなりメモリの内容は普通 0 ですが、0 である必要はなく 0xffffffff でもいいのです。
ただ、0(ヌル) のメモリ表現を 0xffffffff にすると、 言語仕様を破っても アドレス 0 にアクセスできなくなります。
これ意外にも C 言語には size_t、ptrdiff_t のように 言語仕様に定められた型。 alloca、va_arg/var_start/var_end、setjmp/longjmp のように (ライブラリのみでは実装できないので)言語仕様に 入れておいてくれよと言いたくなるような機能が 放置されております。
コンタミは発見の母
雑感なり感想が欲しいナリ (スコア:1)
> Cで書くことができます。... 合わせることすら可能になります。
brake-handle の旦那。そりゃもう反則ですだ。
2つ親のコメントでは移植性の話をしていたし、 この コメント [srad.jp] では、せっかくいいこと書いていたのに inline assembler なんて言語仕様の横穴を認めるなら、 オラ Java でも OS が書けそうな気がしますだ (IBM の Jalapeno みたく)。
p.s.
まじめな話、brake-handle さんが 私の最初のコメント [srad.jp]を読んでどう感じるかが 知りたいです。 個別のポイントではなく、全体として。
コンタミは発見の母
見境なく言語仕様をごみ溜めにするべからず (スコア:1)
意味がよく分かりません。libraryに欠けている機能は何ですか? 言語仕様に入れるべき理由は?
手元にあるFreeBSDのlibcは、allocaもsetjmp/longjmpも実装しています。libraryにしてはいけない理由は見当たりません。同様に、gccだってva_*をきちんと実装しています。
手元で実現してない話をしないように (スコア:1)
全体に対する感想なぞありません。VBで生成したcodeをUnixの元で走らせることに成功したのですか? 現実にやっていないことを話してもらっては困ります。
強いて挙げるとすれば、あなたはOSの束縛から逃れることができていないのでしょう。だから私が一切持ち出していないにもかかわらずあなたはOSのABIの話をしたのです。この時点で残りを読む気が全て失せました。
Re:手元で実現してない話をしないように (スコア:0)
Re:見境なく言語仕様をごみ溜めにするべからず (スコア:1)
また、多くの実装系では va_arg/va_start/va_end はコンパイラによって特殊に処理される擬似関数となっています。単なるライブラリとして書けないものをライブラリの振りをさせるのはまずいでしょう。
> 手元にあるFreeBSDのlibcは、allocaもsetjmp/longjmpも実装しています。
> libraryにしてはいけない理由は見当たりません。
alloca に絞って反論します。
FreeBSD はalloca 関数を本当に libc だけで処理していますか?
コンパイラ(gcc)で特殊な処理を入れていませんか?
少なくとも Linux(x86)上の gcc 2.95.3 では、alloca は擬似関数です。alloca 関数は alloca.h で宣言されたライブラリ関数のように見えますが、実体は違います。 出力されたアセンブラファイルからは外部関数の呼び出しが消え、esp レジスタの操作に変わっています。
私は、このようなコンパイラの支援を要求するものは、ライブラリ関数の範囲から逸脱していると考えています。
コンタミは発見の母
Re:手元で実現してない話をしないように (スコア:1)
> だから私が一切持ち出していないにもかかわらずあなたはOSのABIの話をしたのです。
> この時点で残りを読む気が全て失せました。
私は無論 OS の束縛から逃れていませんが、それを意識しております。
逆に私の目には brake-handle さんが、C 言語が ABI に依存している、つまり
OS やアーキテクチャに束縛されていることに無自覚なように見えます。 これも、C コンパイラが出力したオブジェクトコードがなぜきちんど動作するのかを考えると、
ABI の話が出てきますよね?
> 全体に対する感想なぞありません。VBで生成したcodeをUnixの元で走らせることに成功したの
> ですか? 現実にやっていないことを話してもらっては困ります。
本当に私のコメント [srad.jp]を読まずにレスをつけているのですね。
私のコメントは brake-handle さんのこの [srad.jp]コメントに対するものですよ。
コンタミは発見の母
Re:ナルポインタ (スコア:1)
正確には"無効であることが保証される値"です。内部的には処理系依存。
CPU 0番地が有効な処理系では、内部で違う値を振らなくてはなりません。
別に有効な値でも、処理系が"そこは無効"とする値でもかまいません。
MS-Cはデータセグメントの先頭にNULLを割り当てていましたね。
組み込み系では専用のコンパイラが使われることが多いですが、ANSI標準なんて
ことはまずありません。最初から、NULLに無効な値を定義することだってあります。
-//-
Re:ナルポインタ (スコア:1)
> 別に有効な値でも、処理系が"そこは無効"とする値でもかまいません。
> MS-Cはデータセグメントの先頭にNULLを割り当てていましたね
ですね。
ただ ソースコード上の `0' の表記と、ナルポインタの内部表現を変えた時に、
メモリの 0 番値にどうやってアクセスするかは頭をひねらないといけないと思います。
フラットなメモリ空間を持つシステムで実装を行なうなら、
pointer の内容がメモリアドレスから定数オフセット分ずれていると
するとオーバーヘッドが小さいかしら?
(ポインタの内容) = (メモリアドレス) - (仮想記憶のページサイズ; 例えば 4K)
としておいて、
int* p;
p = (int*)4096;
*p = 0 ; // メモリ 0 番への書き込み
p = 0;
*p = 0 ; // これはヌルポインタへのアクセス。
コンタミは発見の母