アカウント名:
パスワード:
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
ハッカーとクラッカーの違い。大してないと思います -- あるアレゲ
いい方に考えると (スコア:0)
ポインタバリバリ使ってバギーなコード書かれるよりはましかも。
卒業したらJavaに移行して貰えばいいし。
でもコンピュータサイエンティストなら、アセンブラはやって欲しいけどね。
Re:いい方に考えると (スコア:1, すばらしい洞察)
でも、同じ問題は結局JavaだのRubyだのでも生じますよね。ポインタつーか参照については。
単に症状の出方が違う(いきなりコアダンプするか、NullPointerなんたらExceptionが出るか、の違いというか)だけで。
ポインタって、その概念的原理(つまり、なにかがなにかを「参照」する)と、 C独特の構文と、
の2者さえ理解すれば、逆にいえばたいして難関でもないと思います。
あの程度のことを理解*できない*ような人ならば、情報系の学生だろうが仕事だろうが趣味(フリーソフトとか)だろうが
こっちとしてはちょっと
「ポインタ」は「参照」に非ず (スコア:1)
「ポインタ」は「参照」としても利用できるように設計されていますが、「参照」よりも遥かに広いポテンシャルを持った機構です。ゆえにバグの温床となる。
「ポインタ」はメモリアドレスを示す「値」(+型情報)、「参照」はもっと抽象的なオブジェクトやクラスなどを参照することができるデータ。
例えば、言語屋さんから見ると C 言語には "call by reference" がないように見えるそうです。C 言語が "call by reference" と称しているのは、アドレスを渡す "call by value"。
> でも、同じ問題は結局JavaだのRubyだのでも生じますよね。
コンタミは発見の母
Re:「ポインタ」は「参照」に非ず (スコア:2, 参考になる)
>と称しているのは、アドレスを渡す "call by value"。
C言語の文法と挙動を正確に理解できるようになるために学ぶ段階において、
C言語がcall by referenceだなんて考えたらドツボにはまっちゃうわけで。
あくまでcall by valueと考えるべき。
そう考えることで、初学者にもベテランにも言語屋さんにも、誰にとっても
矛盾なく使える(かつ、なにか重要なものを欠落させるわけでもない)モデルが
頭ん中に構築できるわけで。
言語屋さんには見える、
Re:「ポインタ」は「参照」に非ず (スコア:1)
> が可能か不可能か、という差がありますね。 他の変数に代入されてる値にアクセスする、ということ
> が、この機能の有無によって、可能か不可能か変わってくる。
>
> でも逆にいえば、それしか差は無いわけで。
それしか、、、ですか。
私はコンパイラ屋で GC 屋ですから、この 2 つの間に 言語のポテンシャルを完全に
左右する違いを見ているのですが、、、
> あ。ごめん。もうひとつだけ差があった。Cのポインタには「演算」が定義されてる。
> ++とかが出来てしまう
コンタミは発見の母
Re:「ポインタ」は「参照」に非ず (スコア:1)
>左右する違いを見ているのですが、、、
まあそうなんですが、逆にいえば、一言で説明(要約)できるってことは、
その1つの概念を使う(or使わない)べきであるタイミングに
使う(使わない)という選択を明示的かつ自由に行うことが
容易かも知れないことが期待できる(^^;わけで、
実際これについては期待通りなのではないかと実感してまして。
#実感したころにはもう遅い、という説も有りそうだが。
>C 言語のポインタ演算は syntax sugar にすぎないでしょう。
>#define POINTER_INC(P) ((P)=(((char*)P)+sizeof(*P)))
整数との加算、を含めて「ポインタ演算」と呼ぶと記憶していますけど。
++はその派生形っすね。
あとポインタ同士の差という演算も。あれは「ポインタ+整数=ポインタ」という式を
ちょいと移項(懐かしい言葉だ)すれば「ポインタ-ポインタ=整数」という式になるわけで、
説明も理解も(算数を知ってる人なら)簡単。
>C++ の「参照」が、「ポインタ'」にすぎないという点には同意。
C++の「参照」って、ポインタとも所謂参照とも、似てるようで違うようで、
「なんでこんなふーになってんの?」って感じで、いろいろ面倒に感じます(^^;
>JDK1.4 以降の Java には「ポインタ」が入ってきます。
あれ?1.4はまだ全然触ってなかったんですが、Bufferってポインタなのでしたっけ?
生データアクセスを「ラップ」したスマート配列っぽいものかと思ってたんですが…
後で見とくとします。
http://java.sun.com/j2se/1.4/ja/docs/ja/api/java/nio/Buffer.html
http://java.sun.com/j2se/1.4/ja/docs/ja/api/java/nio/ByteBuffer.html
#あ。日本語manはもう出来てたのか。
Re:「ポインタ」は「参照」に非ず (スコア:1)
>>#define POINTER_INC(P) ((P)=(((char*)P)+sizeof(*P)))
>
> 整数との加算、を含めて「ポインタ演算」と呼ぶと記憶しています
> けど。
> ++はその派生形っすね。
あ、すいません。本当に書きたかったのは、下のような手法。
#define POINTER_INC(P) ((P)=(((intptr_t)P)+sizeof(*P)))
ポインタが値であり、適当な整数型との相互キャスト機能を持っていれば、他のポインタ演算は全部代用可能。
>>JDK1.4 以降の Java には「ポインタ」が入ってきます。
> あれ?1.4はまだ全然触ってなかったんですが、Bufferってポインタなのでしたっけ?
> 生データアクセスを「ラップ」したスマート配列っぽいものかと思ってたんですが…
Buffer を Java 単体で使う場合は、その認識でもいいと思います。
でも 本当に Buffer が必要なのは、JavaVM と外部のプログラムとのデータのやり取り。
Buffer は、JNI の先にあるプログラムから見るとポインタでアクセス可能なメモリ空間、同時に Java プログラムからみると配列的なデータ構造をもったオブジェクトに見えます。
コンタミは発見の母
Re:「ポインタ」は「参照」に非ず (スコア:1)
intptr_tって見覚えないなぁと焦って(^^;探したら、これC99の新機能っすか。
http://seclan.dll.jp/c99d/c99d09.htm
なんだかなあ。整数とポインタの相互代入というCのもうひとつの暗部(笑)に、お墨付きを与えたんですね。
所謂ポインタ演算については、使いにくいかも知れないとはいえ、いちおう算数的(?)にマトモだとは思えますが、
整数とポインタの直接変換ってのは、最初から与太だなとしか思えなかったです。与太ゆえに便利だと言ってしまえばそれまでですが。
>ポインタが値であり、適当な整数型との相互キャスト機能を持っていれば、他のポインタ演算は全部代用可能。
ポインタは常に「値」であるような気が…。値でないポインタって何でしたっけ?
あと、C99になってやっと導入された仕組みを使ってはじめて(合法に安全に移植可能に)「全部代用可能」になる、
といわれても、いまいち釈然としないものを感じる古さ(笑)が、俺には有ります。ちょー後付けだなというか。
intptr_t ってそんなにマイナーかしら? (スコア:1)
intptr_t ってそんなにマイナーかしら?
C90 でも OS 側で準備している環境は多いと信じていましたが。
32ビットと64ビット環境を混在させている Solaris や IRIX にはありますし、
Tru64 UNIX でも使えたはずです。HP-UX や AIX にもあると聞くのですが。
# C99 規格の先取りなのか、すでに存在する手法を C99 が取り入れたのか、
# 歴史的経緯はよく知りません。
ポインタを整数型で受ける場合に、直に int 型で受けたりはしないでしょうから、
マクロなり typedef なりで別名をつけますよね。
みなさん、どういう名前を付けているのでしょうか?
ptrdiff_t で受けているのかしら?
p.s.
よく考えれば intptr_t は Ver6 以前の VC にはなかった。
コンタミは発見の母
ポインタ型 ←→ 整数型 (スコア:1)
> を与えたんですね。
前からお墨付きはあったのでは?
ポインタが適切な長さの整数型にキャストできること、その逆変換ができること、
相互変換によって情報が失われないこと、は C コンパイラが保証すべきことだったと記憶していますが。
> > ポインタが値であり、適当な整数型との相互キャスト機能を持っていれば、他のポイ
> > ンタ演算は全部代用可能。
> ポインタは常に「値」であるような気が…。値でないポインタって何でしたっけ?
> あと、C99になってやっと導入された仕組みを使ってはじめて(合法に安全に移植可能
> に)「全部代用可能」になる、といわれても、いまいち釈然としないものを感じる古さ(笑)
> が、俺には有ります。ちょー後付けだなというか。
移植性が問題なのでしょうか?
コンピュータ言語の表面的な文法の話ではなく、ポテンシャルの話をしているのだと思っていたのですが、、、
もう1度繰り返すと、
#148039 [srad.jp]
> あ。ごめん。もうひとつだけ差があった。Cのポインタには「演算」が定義されてる。
> ++とかが出来てしまう。
> で、それらの機構を「参照」に盛り込むことが、べつに論理的に不可能なわけではない。
> ただ実用性において無意味だから誰もやらない(Cを真似ない)だけで。
ポインタがメモリアドレス値を格納するシステムだとすれば、必然的にアドレス値を整数とみなせて相互変換する機能があるはずです
(でないと決めれたアドレスにある VRAM へのアクセスのような使い方ができなくなる)。
もし その機能を持っていれば、++、-- のような他のポインタ演算を代替できます。
ゆえに、C 言語のポインタ演算は「ポインタ」と「参照」を分ける主要な理由とは考えられないということです。
p.s.
私のポインタに対する感覚を把握してもらうためにいいますが、
私は 4 バイトアライメントのシステムではポインタの下位2ビットが必ず 0 になるので、そこをフラグ領域として転用するようなプログラムを書いたりしています。
上位30ビットだけで情報を保持できる「ポインタ」の無節操さと、「参照」を同一視することが私にはできかねます。
コンタミは発見の母
Re:intptr_t ってそんなにマイナーかしら? (スコア:1)
環境依存の分については、極力「目を向けない」ようにしていますので(^^;、知りませんでした。
#自分でdefineしてたら同罪だろ、という指摘は正しいとは思いますが…
># C99 規格の先取りなのか、すでに存在する手法を C99 が取り入れたのか、
環境依存サイドの需要を聞いて、のちに規格が仕組みを供給するようになる、ってのは
まあ珍しいことではないでしょうね。特にこういう感じ(^^;の機能については。
>みなさん、どういう名前を付けているのでしょうか?
そういやGLibにも有りませんでしたっけ。gpointerだっけ?
Re:ポインタ型 ←→ 整数型 (スコア:1)
そでしたっけ?だったら誤認でしたのですんません。
>移植性が問題なのでしょうか?
>コンピュータ言語の表面的な文法の話ではなく、ポテンシャルの話をしているのだと思っていたのですが、、、
移植性も無い、状況しだいで動いたり動かなかったりする(^^;コードに
「潜在」能力を期待するわけにはいかないと思います。
むしろ「潜喪失」能力ってんでしょかね。いつか意図しない形で無くなりかねない(^^;
>ポインタがメモリアドレス値を格納するシステムだとすれば、必然的にアドレス値を整数とみなせて相互変換する機能があるはずです
そういう問題とは別だと思います。
というのは、ポインタに整数を加減できるという性質と、ポインタを整数にCASTできるという性質は、
別々に成立(or不成立)させることが可能だからです。
整数とは別の、あくまでポインタという世界があって、そいつが整数との加減や
++(というか、これも整数との加減の亜種ですね。+=1なのですから。)を定義されている。
ソレが証拠(?)に、ポインタを整数にCASTしたものを++して再び元のポインタにCASTしたものと、
ポインタをそのまま++したものとでは、しばしば(詳細は略していいですね?)同じ値になりません。
整数との加減算は、ポインタを「進める/戻す」という性質のために存在し、
CASTとは別問題であるはず。
>上位30ビットだけで情報を保持できる「ポインタ」の無節操さと、「参照」を同一視することが私にはできかねます。
少なくとも「保持できる」ことは、関係ないし、無節操でもなんでもないと思いますし。
そういやrubyは、それこそ使われない下位bit(最下位1bitだが)を立てることで、ポインタもとい参照を整数に見なすそうです。
Re:ポインタ型 ←→ 整数型 (スコア:2)
>> コンピュータ言語の表面的な文法の話ではなく、ポテンシャルの話をしているのだ
>> と思っていたのですが、、、
> 移植性も無い、状況しだいで動いたり動かなかったりする(^^;コードに
> 「潜在」能力を期待するわけにはいかないと思います。
> むしろ「潜喪失」能力ってんでしょかね。いつか意図しない形で無くなりかねない(^^;
なぜ、私の話をそらすのかなぁ?
コードのポテンシャルの話をしているのではなく、言語機構のポテンシャルの話をしているのです。
過去のコメントの中に、G7さんは「独自の言語を設計し、その実装を行った」とありましたが、その際に言語の中にある別の機能で代用不能な機能と、便利な言い換えを区別して設計しませんでしたか?
>> ポインタがメモリアドレス値を格納するシステムだとすれば、必然的にアドレス値を
>> 整数とみなせて相互変換する機能があるはずです
> そういう問題とは別だと思います。
なぜ?
> 整数とは別の、あくまでポインタという世界があって、そいつが整数との加減や
> ++(というか、これも整数との加減の亜種ですね。+=1なのですから。)を定義されて
> いる。整数との加減算は、ポインタを「進める/戻す」という性質のために存在し、
> CASTとは別問題であるはず。
「目的」や「使用方法」の問題ではないのです。
C 言語の for/while/do-while 文は、if と goto 文とラベルがあれば代替可能です。
for/while/do-while はループをあわわすために存在します。しかし、言語のポテンシャルを増やしている分けではないでしょう?
# for/while/do が不要だといっているわけではない。
無論、私も代替可能である機構のすべてが言語のポテンシャルを広げることに貢献していないとは考えていません。C++ のクラスも C 言語を使って実装可能です(実際初期の C++ 処理系は C++ から C へのトランスレータでした)。しかし、C++ はカプセル化などの機能をプログラマに提供するという意味で、言語のポテンシャルを上げていると考えています。
> というのは、ポインタに整数を加減できるという性質と、ポインタを整数にCAST
> できるという性質は、別々に成立(or不成立)させることが可能だからです。
問題にしているのは、「ポインタに整数を加減でるという性質」と「ポインタを整数にCASTし、その逆変ができる」という性質です。妙なところで端寄るのはやめましょう。
上の2つの機能は独立ではあるが同条件ではありません。「ポインタを整数にCASTし、その逆変ができる」を言語仕様から外すと、処理系非依存の依存の機能を用いない限り、言語のポテンシャルは小さくなります。つまり、実現できない機能がでてきます。
> ソレが証拠(?)に、ポインタを整数にCASTしたものを++して再び元のポインタにCAST
> したものと、ポインタをそのまま++したものとでは、しばしば(詳細は略していいで
> すね?)同じ値になりません。
詳細をあげください。無論、char 型より大きい方のポインタでは一致しないなんては駄目ですよ。私はすでにポインタの指す型のサイズ(sizeof(*pointer))を加えた例を挙げているのですから。このとき両者は同じ値ですね。
それとも、ポインタは参照と型の両方を持っている点が違うといいたいのですか? ポインタ演算を行っている場所では、そのポインタの指す型がどこでも手に入りますよ。つまり、ポインタを整数にキャストして足す時とした場合、その足し幅が手に入るということです。なぜなら、この型の情報を持っているのは実行コンテキストではなく、プログラムのフローだからです。
p.s.
追加しおきますが、ポインタを整数型にキャストして演算し戻し場合と、ポインタ演算の結果が異なる可能性は確かに存在します(C 言語の仕様上)。
おそらく G7 さんが意図したこととは異なるし、この議論とは関係ないので詳細は述べませんが。
# *((int*)0) = 0;
# どのメモリアドレスに値を書き込もうとしているか分かりますか?
p.p.s.
#147884 [srad.jp]の
>>ポインタバリバリ使ってバギーなコード書かれるよりはましかも。
に
> でも、同じ問題は結局JavaだのRubyだのでも生じますよね。ポインタつーか参照に
> ついては。 単に症状の出方が違う(いきなりコアダンプするか、NullPointerなんたら
> Exceptionが出るか、の違いというか)だけで。
と答えたあたりから疑っていたのですが、G7 さんはC言語から Java へ乗り換えることによって、どのようなC言語特有のバグがどのように減るのか
コンタミは発見の母
Re:ポインタ型 ←→ 整数型 (スコア:0)
ところで G7 さんに答えを期待するのは無茶なんではないかと述べさせていただきます。
>なぜ、私の話をそらすのかなぁ?
理解できないか、または、理解しようとしていないと思われます。
>G7 さんはC言語から Java へ乗り換えることによって、どのようなC言