パスワードを忘れた? アカウント作成
この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。

MSが大学に寄付してC#が必修科目に」記事へのコメント

  • by Anonymous Coward
    今更C言語覚えるより良いのかもね。
    ポインタバリバリ使ってバギーなコード書かれるよりはましかも。
    卒業したらJavaに移行して貰えばいいし。

    でもコンピュータサイエンティストなら、アセンブラはやって欲しいけどね。
    • Re:いい方に考えると (スコア:1, すばらしい洞察)

      by G7 (3009) on 2002年08月17日 17時05分 (#147884)
      >ポインタバリバリ使ってバギーなコード書かれるよりはましかも。

      でも、同じ問題は結局JavaだのRubyだのでも生じますよね。ポインタつーか参照については。
      単に症状の出方が違う(いきなりコアダンプするか、NullPointerなんたらExceptionが出るか、の違いというか)だけで。

      ポインタって、その概念的原理(つまり、なにかがなにかを「参照」する)と、 C独特の構文と、
      の2者さえ理解すれば、逆にいえばたいして難関でもないと思います。
      あの程度のことを理解*できない*ような人ならば、情報系の学生だろうが仕事だろうが趣味(フリーソフトとか)だろうが
      こっちとしてはちょっと遠慮願いたいものだ、と思ったりします。

      #ポインタって結局は、四角と矢印の組み合わせからなる図で、ぜんぶ説明できますよね。
      #四角はメモリ領域(byteやWord)。矢印はポインタがどこかの領域を指してる様子。

      そういう意味では、ポインタバリバリでバギーなコードを書いちゃった時点で、その人の
      (Cに限らない)プログラミング能力を、俺は疑いますね。

      ただ、Cがメインの学習カリキュラムってのもそれはそれで痛いってことならば、同意。

      あとは、都市伝説よりきちんとした定義を学ぶ、ということを知ってる人でないと駄目ですね。
      C言語なりポインタなりについて(というか他のどれでもそうだが)、
      正しい理解をしている人は、たいていいつも正しいコードを書き、
      あやふやでバギーな理解(^^;をしてる人は、書くコードもバギーです。
      自分が抱えてる知識(やそれへの参照)が正しいかどうか?を、きちんと身辺整理できる人でないと、ちょっとね。

      >でもコンピュータサイエンティストなら、アセンブラはやって欲しいけどね。

      それってハードウェアサイエンティストのことですか?ソフト(上層)ではなくて?
      親コメント
      • >でもコンピュータサイエンティストなら、アセンブラはやって欲しいけどね。
        それってハードウェアサイエンティストのことですか?ソフト(上層)ではなくて?

        サイエンティストがアセンブラやるべきかどうかは分からないけど、エンジニアならやっておくべきかも。

        例えばここで話題になっているC言語のポインタにしても、最初に

        #ポインタって結局は、四角と矢印の組み合わせからなる図で、ぜんぶ説明できますよね。
        なんていう風に端から抽象化して説明されちゃうと、かえって分かりづらくなると思うのです(JavaやLispのような動的メモリ管理をしてくれる言語だとそれでもなんとかなるかもしれませんが)。最初はむしろ具体的に、インデックスレジスタ(アドレスレジスタ)でアドレッシングするんだよ、というような、
        #四角はメモリ領域(byteやWord)。矢印はポインタがどこかの領域を指してる様子。
        という方に近い説明の方が直截的で分かりやすいと(私は)思います。「C言語とは高級アセンブラの一種である」なんていうことを言う人もいますが、後でCを使うのならアセンブラから入るのが反って分かりやすい(場合もある)というのが私の考えです。

        ま、この辺り、メモリ上の具体的なイメージさえ湧くなら、アセンブラやらなくてもC言語をやれば良いということも言えますけどもね。C言語と聞いてまず「ポインタ! 理解不能!」と思っちゃう人は、たぶんアセンブラを知らない人に限られるんじゃないかなあと思います。(検証したことはないですが)

        ただ、以上は「泥臭いプログラミングもできなきゃいけない」エンジニアにとっては学ぶべき範疇と思いますが、大学の(コマ数の限られた)教養で学ぶプログラミングの知識として適切かというと、それはまた別の問題ですね。そういう意味では、個人的には、やっぱLispを推しちゃうかな。あるいはMLとかもいいかなあ。

        ま、ぢつはLispもアセンブラ知ってた方が分かりやすいって面もあるけどネ^^;。なにせCARだのCDRだのの語源がそもそもアセンブラらしいし……。抽象的議論に耐え、かつぢつは結構泥臭い、てところがLispのミ・リョ・ク☆ :-) どうせ限られた数の言語しかやらないなら、後で訳もなく愛せてしまう言語を選ぶってのもいいカモネ! :-) :-)

        その点C#はどうなのかな?

        親コメント
        • >なんていう風に端から抽象化して説明されちゃうと、かえって分かりづらくなると思うのです

          そう?俺はそのほうが判り易いと、昔も今も思っているけど?

          四角だの矢印だのの絵を、いきなり具体的な(具体的ゆえに、レジスタだのメモリだのといった
          記憶領域の種類が複数有って不均質だったり、銘柄ごとに非互換だったりする)モデルに
          マップして考えようとすると、その具体的ぶりに「振り回されて」しまうと思います。

          俺もCの後で少しアセンブラやったりしましたが、
          アセンブラをやる前と後とで、Cを書いたときに出すバグの量が
          劇的に変わった(減った)なんてなことは、無かったです。
          つまりCへの理解モデルは、アセンブラに影響されなかった(される必要がなかった)わけです(^^;

          「メモリつーものがあるらしいぞ。1次元配列らしいぞ。」「ふーん」
          という程度の具体性しかないモデルで理解しておくほうが、楽でしたね。
          実際、C言語がメモリについて担当している抽象化は、まさにそういう部分なのであって。

          実際、例えば、CPUが備えているIndexレジスタの数を遥かに超えた数のポインタ変数を作れるC言語
          を理解するにあたって、Indexレジスタ(とメモリとの値のやりとり!(レジスタが指す領域の話じゃないですよ))を
          いちいち意識するほうが「理解」が進むとは、ちょっと思えません。

          なお、四角の絵には工夫があります。#って、べつに俺がした工夫ではなく、たしかK&Rでもそうなってたような…
          「連続した」メモリ領域は、四角もまた「連続して」並べて描く。
          「連続しない」領域は、四角も離して描く。
          こうして、絵に「適度な(過剰でない)」具体性を与えることで、それは十分な情報を人に伝えられる媒体になる、と思えます。
          過剰な具体性はウザイだけです。

          >メモリ上の具体的なイメージさえ湧くなら、アセンブラやらなくてもC言語をやれば良いということも言えますけど
          >もね。C言語と聞いてまず「ポインタ! 理解不能!」と思っちゃう人は、たぶんアセンブラを知らない人に限られるんじゃないかなあ

          「抽象的な」イメージでもOK(なことも有る;-P)と思います。
          アセンブラ知ってればポインタOKってのはTRUEなのかも知れません(俺は知りません)が、
          逆にポインタOKになるための条件としてアセンブラが有るわけでは、ないと思います。

          >ま、ぢつはLispもアセンブラ知ってた方が分かりやすいって面もあるけどネ^^;。なにせCARだのCDRだのの語源がそもそもアセンブラらしいし……。

          出自に絡んでたまたま設定された用語の1つ2つですから、関係ないと思うけどな;-P
          上記の抽象化されたメモリのモデルで、(C以上に)あっさり説明可能であって、それ以上は要らないっす。
          親コメント
      • 「ポインタ」と「参照」は異なる機構ですよ。
        「ポインタ」は「参照」としても利用できるように設計されていますが、「参照」よりも遥かに広いポテンシャルを持った機構です。ゆえにバグの温床となる。

        「ポインタ」はメモリアドレスを示す「値」(+型情報)、「参照」はもっと抽象的なオブジェクトやクラスなどを参照することができるデータ。

        例えば、言語屋さんから見ると C 言語には "call by reference" がないように見えるそうです。C 言語が "call by reference" と称しているのは、アドレスを渡す "call by value"。

        > でも、同じ問題は結局JavaだのRubyだのでも生じますよね。ポインタつーか参照に
        > ついては。単に症状の出方が違う(いきなりコアダンプするか、NullPointerなんたら
        > Exceptionが出るか、の違いというか)だけで。

        いいえ。
        例えば、下記のようなコードの問題は Java では生じません。記述もできません。
        これは大きな違いです。

            int a = 0;
            int b = 0;
            int c = 0;
            int* p = &b;
            *(p + 1) = 1;
            printf( "a=%d, c=%d\n", a, c );
        --
        コンタミは発見の母
        親コメント
        • by G7 (3009) on 2002年08月18日 0時50分 (#148039)
          >例えば、言語屋さんから見ると C 言語には "call by reference" がないように見えるそうです。C 言語が "call by reference"
          >と称しているのは、アドレスを渡す "call by value"。

          C言語の文法と挙動を正確に理解できるようになるために学ぶ段階において、
          C言語がcall by referenceだなんて考えたらドツボにはまっちゃうわけで。

          あくまでcall by valueと考えるべき。

          そう考えることで、初学者にもベテランにも言語屋さんにも、誰にとっても
          矛盾なく使える(かつ、なにか重要なものを欠落させるわけでもない)モデルが
          頭ん中に構築できるわけで。

          言語屋さんには見える、という狭い話じゃなくて、誰にでもそれは事実であるのでは?

          >例えば、下記のようなコードの問題は Java では生じません。記述もできません。
          >int* p = &b;

          ああ。これは失礼。
          CのポインタとJavaとかの参照との違いとして、「データじゃなく変数(データの器)を」指すということが
          可能か不可能か、という差がありますね。
          他の変数に代入されてる値にアクセスする、ということが、この機能の有無によって、可能か不可能か変わってくる。

          でも逆にいえば、それしか差は無いわけで。

          あ。ごめん。もうひとつだけ差があった。Cのポインタには「演算」が定義されてる。
          ++とかが出来てしまう。

          で、それらの機構を「参照」に盛り込むことが、べつに論理的に不可能なわけではない。
          ただ実用性において無意味だから誰もやらない(Cを真似ない)だけで。

          余談:
          C++の参照と、それ以外の多くの言語(JavaとかRubyとかDelphiとかLispとか…)の参照とを混同している人が
          近傍に居るようですが(^^;、まぁそれはそのぉ…って感じ。
          C++って、用語の変さという意味でも、痛い言語なんだよな。時として他の言語を学ぶのを妨げかねない。
          親コメント
          • by moonbear (4602) on 2002年08月18日 1時05分 (#148047)
            メカニズムが簡単なのと,その扱いが多くの人にとって簡単であるということは全く別です.G7さんはおそらくJavaやLispにおける参照が,実装レベルでどのように(ある制約にしたがった)ポインタとして扱われているかを理解しているので,あまりC/C++でも困っていないのではないでしょうか(憶測モード).

            ただ,現実に多くの人がポインタの理解で苦しんでいるのは事実のようです.またC/C++のポインタはプログラムの解析を行う際にも様々な困難を引き起こすのですが,そのことも使うのが難しいということを裏付けていると思います.
            親コメント
            • >メカニズムが簡単なのと,その扱いが多くの人にとって簡単であるということは全く別です

              そりゃまあそうですが、ポインタについては、難しいですかね?
              K&Rを正しく(=変に我流で憶測せずに字面どおりに寸分(?)違わず)理解すれば(^^;、べつに躓いた記憶が無いんですけど。

              #逆にいえば、そういう「完全に信頼した上での」読み方が出来る本(や先生)がもし無ければ、辛いですけど。

              ポインタの難しさは、なんというか、Fragileというか、触り方を間違えたら壊れる、という難しさは感じますね。
              しかし、それは個々の手の動きレベルの問題で、それ以前の概念の段階では、別に難しくないような。
              前述の四角モデル以上のものを必要だと感じたことが無いです。

              #Cのポインタまわりの文法という意味では、難しいというか、煩雑というか、わけわかだとは思いますけどね(T_T)

              >G7さんはおそらくJavaやLispに
              >おける参照が,実装レベルでどのように(ある制約にしたがった)ポインタとして扱われているかを理解しているので,あま
              >りC/C++でも困っていないのではないでしょうか(憶測モード).

              うーん。動く言語(文法も内部表現も)を作った事が有る(実装手段はC)からには、理解してるってことになるんでしょーけど、
              そういう問題じゃないような気がするなあ。
              CもJavaも、全く同じじゃなく微妙に違うものの、どちらも四角モデルで表現できちゃうわけで。

              >ただ,現実に多くの人がポインタの理解で苦しんでいるのは事実のようです.

              現象としてそれは真ですが、理由の説明が正しいかどうかは別じゃないかな。

              俺は、もっと違う理由によって、ポインタに躓く人が生まれてるんじゃないか、と思っています。
              で、俺の邪推では、それは、誤解の伝播なのではないかと。つまり教える側が誤解してて
              その誤解が生徒にも伝播する、のサイクルを繰り返してると。

              あとは別口でも書いたような「都市伝説」問題かな。誤解を正さないまま放置してるという。
              #ポインタは難しいというの自体が伝説だと思いますね。それを聞いた人がポインタの理解を途中で放棄しちゃう。
              そしてその根底には、理解を我流の憶測で補完しようとする日本人(?)の悪癖の問題が、横たわっていると思う。

              つまり、正しく(かつ出来れば平明に)教えてる人の言葉を、正しく聞けば、
              そう簡単にハマらないようなプログラマになれると思うんですけどね。とりあえずポインタについては。

              そういや逆にいえば、Cポインタだけじゃなく、Javaとかでいう意味の参照もまた、
              理解に苦しんでいる人が結構居るようですよね。うーん。困ったもんだ。
              #WWWが流行してるんだから、参照というもの自体が人間に理解しにくい、という訳じゃ無い筈なんだが…

              >またC/C++のポインタはプログラムの解析を行う際にも様々な困難を引き起こすのですが,
              >そのことも使うのが難しいということを裏付けていると思います.

              うーん。解析ってのは、そのプログラムにおけるそのポインタの意味を「読む」ほうの問題ですよね?
              一方でプログラマの卵(?)が悩むのはポインタの意味を「書く(作る)」ほうの問題ですよね。

              読むのが楽(大変)なものと、書くのが楽(大変)なものとは、必ずしもイコールではない、のではないでしょうか?
              親コメント
          • > CのポインタとJavaとかの参照との違いとして、「データじゃなく変数(データの器)を」指すということ
            > が可能か不可能か、という差がありますね。 他の変数に代入されてる値にアクセスする、ということ
            > が、この機能の有無によって、可能か不可能か変わってくる。
            >
            > でも逆にいえば、それしか差は無いわけで。

            それしか、、、ですか。
            私はコンパイラ屋で GC 屋ですから、この 2 つの間に 言語のポテンシャルを完全に
            左右する違いを見ているのですが、、、

            > あ。ごめん。もうひとつだけ差があった。Cのポインタには「演算」が定義されてる。
            > ++とかが出来てしまう。

            C 言語のポインタ演算は syntax sugar にすぎないでしょう。
            ないと不便ですけど。

                #define POINTER_INC(P) ((P)=(((char*)P)+sizeof(*P)))

            p.s.

            > 余談:
            > C++の参照と、それ以外の多くの言語(JavaとかRubyとかDelphiとかLispとか…)の参照とを混同して
            > いる人が近傍に居るようですが(^^;、まぁそれはそのぉ…って感じ。
            本当だ。しきい値を上げているので分かりませんでした。
            C++ の「参照」が、「ポインタ'」にすぎないという点には同意。

            p.p.s.

            JDK1.4 以降の Java には「ポインタ」が入ってきます。
            Buffer というやつ。トホホ。
            --
            コンタミは発見の母
            親コメント
            • >私はコンパイラ屋で GC 屋ですから、この 2 つの間に言語のポテンシャルを完全に
              >左右する違いを見ているのですが、、、

              まあそうなんですが、逆にいえば、一言で説明(要約)できるってことは、
              その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はもう出来てたのか。
              親コメント
              • >>C 言語のポインタ演算は syntax sugar にすぎないでしょう。
                >>#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 プログラムからみると配列的なデータ構造をもったオブジェクトに見えます。
                --
                コンタミは発見の母
                親コメント
              • >#define POINTER_INC(P) ((P)=(((intptr_t)P)+sizeof(*P)))

                intptr_tって見覚えないなぁと焦って(^^;探したら、これC99の新機能っすか。
                http://seclan.dll.jp/c99d/c99d09.htm

                なんだかなあ。整数とポインタの相互代入というCのもうひとつの暗部(笑)に、お墨付きを与えたんですね。
                所謂ポインタ演算については、使いにくいかも知れないとはいえ、いちおう算数的(?)にマトモだとは思えますが、
                整数とポインタの直接変換ってのは、最初から与太だなとしか思えなかったです。与太ゆえに便利だと言ってしまえばそれまでですが。

                >ポインタが値であり、適当な整数型との相互キャスト機能を持っていれば、他のポインタ演算は全部代用可能。

                ポインタは常に「値」であるような気が…。値でないポインタって何でしたっけ?

                あと、C99になってやっと導入された仕組みを使ってはじめて(合法に安全に移植可能に)「全部代用可能」になる、
                といわれても、いまいち釈然としないものを感じる古さ(笑)が、俺には有ります。ちょー後付けだなというか。
                親コメント
              • > intptr_tって見覚えないなぁと焦って(^^;探したら、これC99の新機能っすか。

                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 にはなかった。
                --
                コンタミは発見の母
                親コメント
              • > なんだかなあ。整数とポインタの相互代入というCのもうひとつの暗部(笑)に、お墨付き
                > を与えたんですね。
                前からお墨付きはあったのでは?
                ポインタが適切な長さの整数型にキャストできること、その逆変換ができること、
                相互変換によって情報が失われないこと、は C コンパイラが保証すべきことだったと記憶していますが。

                > > ポインタが値であり、適当な整数型との相互キャスト機能を持っていれば、他のポイ
                > > ンタ演算は全部代用可能。
                > ポインタは常に「値」であるような気が…。値でないポインタって何でしたっけ?
                > あと、C99になってやっと導入された仕組みを使ってはじめて(合法に安全に移植可能
                > に)「全部代用可能」になる、といわれても、いまいち釈然としないものを感じる古さ(笑)
                > が、俺には有ります。ちょー後付けだなというか。

                移植性が問題なのでしょうか?
                コンピュータ言語の表面的な文法の話ではなく、ポテンシャルの話をしているのだと思っていたのですが、、、

                もう1度繰り返すと、
                #148039 [srad.jp]
                > あ。ごめん。もうひとつだけ差があった。Cのポインタには「演算」が定義されてる。
                > ++とかが出来てしまう。
                > で、それらの機構を「参照」に盛り込むことが、べつに論理的に不可能なわけではない。
                > ただ実用性において無意味だから誰もやらない(Cを真似ない)だけで。

                ポインタがメモリアドレス値を格納するシステムだとすれば、必然的にアドレス値を整数とみなせて相互変換する機能があるはずです
                (でないと決めれたアドレスにある VRAM へのアクセスのような使い方ができなくなる)。
                もし その機能を持っていれば、++、-- のような他のポインタ演算を代替できます。

                ゆえに、C 言語のポインタ演算は「ポインタ」と「参照」を分ける主要な理由とは考えられないということです。

                p.s.

                私のポインタに対する感覚を把握してもらうためにいいますが、
                私は 4 バイトアライメントのシステムではポインタの下位2ビットが必ず 0 になるので、そこをフラグ領域として転用するようなプログラムを書いたりしています。
                上位30ビットだけで情報を保持できる「ポインタ」の無節操さと、「参照」を同一視することが私にはできかねます。
                --
                コンタミは発見の母
                親コメント
              • >C90 でも OS 側で準備している環境は多いと信じていましたが。

                環境依存の分については、極力「目を向けない」ようにしていますので(^^;、知りませんでした。
                #自分でdefineしてたら同罪だろ、という指摘は正しいとは思いますが…

                ># C99 規格の先取りなのか、すでに存在する手法を C99 が取り入れたのか、

                環境依存サイドの需要を聞いて、のちに規格が仕組みを供給するようになる、ってのは
                まあ珍しいことではないでしょうね。特にこういう感じ(^^;の機能については。

                >みなさん、どういう名前を付けているのでしょうか?

                そういやGLibにも有りませんでしたっけ。gpointerだっけ?
                親コメント
              • by G7 (3009) on 2002年08月20日 23時14分 (#149742)
                >前からお墨付きはあったのでは?

                そでしたっけ?だったら誤認でしたのですんません。

                >移植性が問題なのでしょうか?
                >コンピュータ言語の表面的な文法の話ではなく、ポテンシャルの話をしているのだと思っていたのですが、、、

                移植性も無い、状況しだいで動いたり動かなかったりする(^^;コードに
                「潜在」能力を期待するわけにはいかないと思います。
                むしろ「潜喪失」能力ってんでしょかね。いつか意図しない形で無くなりかねない(^^;

                >ポインタがメモリアドレス値を格納するシステムだとすれば、必然的にアドレス値を整数とみなせて相互変換する機能があるはずです

                そういう問題とは別だと思います。

                というのは、ポインタに整数を加減できるという性質と、ポインタを整数にCASTできるという性質は、
                別々に成立(or不成立)させることが可能だからです。

                整数とは別の、あくまでポインタという世界があって、そいつが整数との加減や
                ++(というか、これも整数との加減の亜種ですね。+=1なのですから。)を定義されている。

                ソレが証拠(?)に、ポインタを整数にCASTしたものを++して再び元のポインタにCASTしたものと、
                ポインタをそのまま++したものとでは、しばしば(詳細は略していいですね?)同じ値になりません。

                整数との加減算は、ポインタを「進める/戻す」という性質のために存在し、
                CASTとは別問題であるはず。

                >上位30ビットだけで情報を保持できる「ポインタ」の無節操さと、「参照」を同一視することが私にはできかねます。

                少なくとも「保持できる」ことは、関係ないし、無節操でもなんでもないと思いますし。

                そういやrubyは、それこそ使われない下位bit(最下位1bitだが)を立てることで、ポインタもとい参照を整数に見なすそうです。
                親コメント
              • >> 移植性が問題なのでしょうか?
                >> コンピュータ言語の表面的な文法の話ではなく、ポテンシャルの話をしているのだ
                >> と思っていたのですが、、、
                > 移植性も無い、状況しだいで動いたり動かなかったりする(^^;コードに
                > 「潜在」能力を期待するわけにはいかないと思います。
                > むしろ「潜喪失」能力ってんでしょかね。いつか意図しない形で無くなりかねない(^^;

                なぜ、私の話をそらすのかなぁ?
                コードのポテンシャルの話をしているのではなく、言語機構のポテンシャルの話をしているのです。
                過去のコメントの中に、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言語特有のバグがどのように減るのか
                --
                コンタミは発見の母
                親コメント
          • >> 例えば、言語屋さんから見ると C 言語には "call by reference" がないように見えるそうです。
            >> C 言語が "call by reference" と称しているのは、アドレスを渡す "call by value"。
            >
            > C言語の文法と挙動を正確に理解できるようになるために学ぶ段階において、
            > C言語がcall by referenceだなんて考えたらドツボにはまっちゃうわけで。
            >
            > あくまでcall by valueと考えるべき。
            >
            > そう考えることで、初学者にもベテランにも言語屋さんにも、誰にとっても
            > 矛盾なく使える(かつ、なにか重要なものを欠落させるわけでもない)モデルが
            > 頭ん中に構築できるわけで。
            >
            > 言語屋さんには見える、という狭い話じゃなくて、誰にでもそれは事実であるのでは?

            無論 そうですが、C はポインタを引数にした関数呼び出しを "call by reference" で
            あると言っていますよね。実際、そう習う人も多いはずです。

            しかし、通常の C の実装系の挙動を考えるなら、究極的には "call by value" と考えざるえない。それは「ポインタ」と「参照」の間にある違いに起因している、と言いたいわけです。

            実際、ポインタの引数渡しを "call by value" として、捕らえなければプログラムというのは、他のポインタのない言語ではコーディングできない場合が多いでしょう。
            --
            コンタミは発見の母
            親コメント
            • >しかし、通常の C の実装系の挙動を考えるなら、究極的には "call by value" と考えざるえない。それは「ポインタ」と「
              >参照」の間にある違いに起因している、と言いたいわけです。

              それはまた微妙に違う問題であるような…
              JavaやRubyの参照だって、参照という名の値(Value)をコピってるわけでして。

              「変数」を(代入を直接記述する以外の手段で)書き換え可能か、それとも書き換え可能なのは参照先の「データ」だけなのか、
              という差があるのでわないかと。
              ちなみにPascalのVar渡しは変数を書き換え可能っすね。Fortranはどうだっけ?
              親コメント
      • >>でもコンピュータサイエンティストなら、アセンブラはやって欲しいけどね。
        >それってハードウェアサイエンティストのことですか?ソフト(上層)ではなくて?

        ソフトもです。
        自分の書いたコードがどのように解釈されて実行されてるの
        • by Anonymous Coward on 2002年08月17日 17時25分 (#147891)
          地域密着でおばあちゃん相手に預金獲得の営業してる単なる銀行マンに「銀行に勤めるならデリバティブぐらい軽く出来なきゃね」って言ってるようなもの。

          必要な場所で必要な知識があればよし。それ以上を求めてもきりがない。

          理想と現実は違うものだよ。技術者としての理想と、仕事としてのスキルは全くの別問題。
          親コメント
          • by moonbear (4602) on 2002年08月17日 22時22分 (#147980)
            もとのコメントの対象が「コンピュータサイエンティスト」ということなので,この例えはあんまりそぐわない気がします.

            もっとも現役のコンピュータサイエンティストと言われている人達は,いざとなればアセンブラでプログラムを書くことくらいはできると思いますがね.

            案外そうでも無いのかな? :-P
            親コメント
        • by G7 (3009) on 2002年08月17日 18時18分 (#147905)
          >そのへんの知識がないとパフォーマンスチューニングだの、コンパイラのバグだのに直面
          >した時対処出来ない。

          >こういうのはVB屋さんとかにダメな人が多いね。

          こういう文脈でVB屋を引き合いに出すなんて、コンパイラ屋さん(なのかな?)のやることじゃないですね。
          優劣はさておくとしても「畑」が違いすぎるんだから、その畑での勝負は、結果が目に見えている出来レースです。

          逆に、下層に強い人だからといって、上層もすらすらこなせるとは限らないと思うんですが、どうなんでしょう?
          下層でやってることを再帰的に積み重ねる「だけ」で上層も説明できるわけでは、無い筈ですから。

          よだん:
          パフォチューといえばDBマガジンなんかでも(もちろんDB畑について)よく記事が乗るようです。
          まぁ色々あるということで。

          よだん2:
          ここでは関係ない話であることを期待します(笑)が、
          「自分のバグを見逃して、コンパイラのバグだと騒ぐ」人も結構いるらしいですね。
          上層やってる側から言えば、いかにコンパイラのバグみたいなものを「踏まず」にいられるような
          素朴(笑)なコードで実装を済ますか?を気にしたりは、します。
          親コメント
          • >逆に、下層に強い人だからといって、上層もすらすらこなせるとは限らないと思うんですが、どうなんでしょう?

            下層がわからなくて上層はできないと思うのですが。
            それってたまたまうまくいってるだけとかできてるつもりなだけなのでは?
            • 理想としては、下層が分からなくても上層が完璧に出来る状況があれば良いのですが、
              資源的にそれが許されない場合が多いし、下層がわからないとメモリリークとか違法参 照とかしまくる状況なのが今のコンピュータソフトですからね…

              はっきり言えるのは、難問に直面した場合、アセンブラやハードウェアをやった人の方 が的確な答えに到達するのが速いと言う事ですね。
              その状況が5年先、10年先も続くかどうかは明言できないですが…

              親コメント
              • by Carol (2812) on 2002年08月18日 10時28分 (#148152)
                でも、APIとかDLL使っててVB上で原因不明のエラーが出ててトレースしようと思ったらアセンブラの知識いりますよね。
                #まぁ滅多にそんなことにはならないですけど
                親コメント
              • by G7 (3009) on 2002年08月18日 13時18分 (#148202)
                >話の流れから、上層とはVBやC#あるいはもっと上のDBMSなどを指していると思うのですが、

                Javaとかみたいな仮想マシンの「上」の世界の話も指してますね。

                >アセンブラやハードウェアを知っていれば解決しやすいメモリリークとか違法参照なんてありますか?

                ぎゃはは。鋭い。スラド風にいえば「すばらしい洞察」!
                モデレは(もし権利あっても)しない主義なので、ここでこうして生の言葉で賞賛させて頂きますm(__)m。

                >直下層の知識は役に立つことが多いと思います。
                >が、なんでもかんでも最下層の知識を求めようとすると
                (以下略)

                御意。なるほど、直下かあ。
                Javaとかで、参照の意味的なバグを出しちゃった状態で、アセンブラレベルの知識が直接役立つのか?と聞かれると、
                たしかに首をかしげます。

                それぞれのバグには、そのバグに見合った抽象度(^^;の対策が、有るってことでしょうね。
                それより上すぎても下すぎても、対策として的外れなものになっちゃう、と。

                そしてCのポインタにしても、抽象的な理解によって退治できる(すべき)バグと、
                ハード寄りの理解によって退治できる(すべき)バグと、が有るんでしょうね。

                ただし、高級言語たるものの役目はもともと抽象化であるわけですから、
                その役割を全うしてる限り頻繁に必要とはならないはずの具体的な理解
                (さもないと「シゴトで使える言語」という前提が崩れます。ポインタみたいな重要なところでバグにぶちあたるコンパイラなんて、
                速攻で直す(そして明日からはバグに悩まされない)か、速攻で捨てるか、回避コードで逃げるか、どれかしないと仕事にならんでしょ)
                を常時持っていることよりも、
                むしろ抽象的な理解を常時持っていることのほうが、数段重要であるのではないかな。

                余談:
                「理解の深さ」と、ハードからアプリにいたるまでの「階層の深さ」とを、混同してる人が居るような気がする…
                親コメント
            • > 下層がわからなくて上層はできないと思うのですが。
              > それってたまたまうまくいってるだけとかできてるつもりなだけなのでは?

              全てのJavaプログラマはJava仮想マシンを勉強する必要がありますか?
            • 下層が分からんと、上層が開発できないようなシステムの作りはダメダメばシステムでは?

              # 何の為の抽象化?
      • by Anonymous Coward

        ポインタって、その概念的原理(つまり、なにかがなにかを「参照」する)と、 C独特の構文と、 の2者さえ理解すれば、逆にいえばたいして難関でもないと思います。
        --------8<------8=--------
        そういう意味では、ポインタバリバリでバギーなコードを書いちゃった時点で、その人の (Cに限らない)プログラミング能力を、俺は疑いますね。

        ンなことはないって.
        ポインタ(Cみたいな素のポインタ)が問題なのは

アレゲはアレゲを呼ぶ -- ある傍観者

処理中...