アカウント名:
パスワード:
deleteは記憶領域を返却するだけでなく、デストラクタも走ることをご存知ないですか?
だから何?デストラクタが走るのと所有権管理にどんな関係があると?ポインタを複製してもちゃんと管理してくれるとでも?というかデストラクタを書くのは誰?...あー、書く必要がない人なのね。
ポインタは参照や反復子を実装する手段に過ぎないともいえますね。
言えない。順序が逆。既に上げてある通りポインタを反復子として使えない使い方もある。
抽象度が高い複雑な案件でも、パフォーマンスを上げたい部分は
newで生成されたオブジェクトを指すポインタは、それを削除するための情報も内包している。
例としては文字列でもいいけど、たとえば下みたいな構造体は「ポインタは先頭を指しているだけ」という性質を使ったもの。この場合はサイズが不正なのでポインタを反復子としては使えない。struct HOGE{ ほげふが char buff[0];};
こらこら、嘘を書いちゃいかん。 自動的に const int *buff; みたいな変数宣言がされ、buffが buff[0]を指すように初期化されると思っていますか? そんな高度なことは、C/C++コンパイラはやりません。 表記が違うだけで、&buff[0]もbuffも同じものを表します。
もしかすると、あなたは *(buf+2) と buf[2] を違うものだと考えてたりしませんか?
buffは&buff[0]を指すconstポインタ。
なるほど、sizeof(buf)のような時ですね。 C/C++の言語仕様そのものがすごくコンパクトに作られているのは認めますが、ミスを誘発するような仕様が幾つかあるのが残念ですね。 char s[20] = "hello world!"; なんて記述は、便利だけど酷い仕様です。
あなたの言う「配列の先頭を指すconstポインタ」を指すポインタ変数を定義し、どのように使うのか見せてください。
コンパイル時に解決されるか、ランタイム実行時に解決されるかは処理系依存です。 printf("%d\n", sizeof(buff)); の結果がどうなるかやってみ。 あなたの言うconstポインタとかいうもののサイズが分かるから。
&c の&は、"&演算子"です。&演算子は直後の変数のアドレスを取り出すという演算を行います。&cは、変数cのアドレスを求めるという演算です。 &cを、コンパイル時に相対アドレスとして解決する処
レジスタ変数のアドレスを取得可能な処理系を使ったことがある。 register変数は必ず、CPUレジスタ上に置かねばならないという規約はないので、変数のアドレスをとるような処理がある場合はメモリ上にその変数の領域を確保するようにしていたようです。そもそもregisterという概念そのものがないCPUも存在するし、register変数をどのように実現するかは処理系依存だと思います。C言語の規約には、どのように動作するのが望ましいということが、書かれていそうです。
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
アレゲはアレゲ以上のなにものでもなさげ -- アレゲ研究家
まぁ、驚いたのは (スコア:0)
指摘されても問題が何か理解出来ていない編集にはビックリだな
Re: (スコア:2, 興味深い)
自分でプログラミングすることなんか全く無いんでしょうね。
Re: (スコア:1, すばらしい洞察)
ポインタがいまいち理解できない人には朗報だ。
Re: (スコア:0, すばらしい洞察)
それで正しいと思います。
Cのポインタは、
- スカラ値への参照
- 配列への参照
- 動的オブジェクトの所有権管理
- 反復子
これら全然違う概念を一個で実現しようとする、そもそも無茶なキメラですよ。
私はC++使いなんですが、C++なら、状況によって参照やスマートポインタや反復子を使い分けるところです。
理解しようとするとかえって遠回りだと思います。
Re: (スコア:1, すばらしい洞察)
>動的オブジェクトの所有権管理
CもC++もそんなことはやってくれないよ?
所有権はプログラマが自分で管理するか管理するためのコードを書く。これ基本。でないとメモリリークし放題。
んとなー?抽象度の高い方から理解しようとするから理解できないんだよ。
ポインタを理解するにはメモリイメージを持つこと。これに尽きる。
Re:まぁ、驚いたのは (スコア:0)
明示的にdeleteするのも所有権管理の範疇ではないでしょうか?
>ポインタを理解するにはメモリイメージを持つこと。これに尽きる。
その通りです。抽象度の高い課題には不要な理解で、生産性を下げます。
Re:まぁ、驚いたのは (スコア:1)
感覚の問題かも知れんが、少なくとも俺はそうは思わない。
なぜならその例でいうdeleteで言えばnew/deleteとは無関係にポインタでアクセスできてしまうから。
「*(int*)0 = 0;」みたいないきなり「ぬるぽガッ」なコードだって書けちゃうし。
もしnew/deleteを所有権の管理とするなら所有する主体(主語)はオブジェクトではなくプロセスという解釈が必要になる。
でも、そうだとしてそれに意味があるのかどうかはかなり疑問。
>抽象度の高い課題には不要な理解で、生産性を下げます。
不要かどうかは別にして、それはそう。
だからそういう課題でパフォーマンス的にも細かい事言われないならC/C++はそもそも不向き。
Re: (スコア:0)
>「*(int*)0 = 0;」みたいないきなり「ぬるぽガッ」なコードだって書けちゃうし。
その通りです。所有権管理と参照は分離されるべきなのです。
だけどCのポインタは分離されてないよね、というのが前言の趣旨です。
>だからそういう課題でパフォーマンス的にも細かい事言われないならC/C++はそもそも不向き。
パフォーマンスが重要な案件でも、チューニングが必要なのは一部です。
Re: (スコア:0, フレームのもと)
分離されてないも何もさっきから言ってるように、そもそもポインタには所有権管理機能なんてないんだってば。
new/deleteやmalloc/freeはプロセスがメモリ空間を占有するものであって、ポインタがその確保した領域を占有するというものではないよ。
そもそもポインタは先頭を指してるだけであって領域のことなんか知ったこっちゃない。
例としては文字列でもいいけど、たとえば下みたいな構造体は「ポインタは先頭を指しているだけ」という性質を使ったもの。
この場合はサイズが不正なのでポインタを反復子としては使えな
Re: (スコア:0, フレームのもと)
だから何?デストラクタが走るのと所有権管理にどんな関係があると?
ポインタを複製してもちゃんと管理してくれるとでも?
というかデストラクタを書くのは誰?
...あー、書く必要がない人なのね。
言えない。順序が逆。
既に上げてある通りポインタを反復子として使えない使い方もある。
Re:まぁ、驚いたのは (スコア:1)
たしかにnewすると確保サイズが保存されてdeleteでちゃんと戻してくれる。でもそれはポインタの機能じゃなくてnewとdeleteの機能。ポインタに確保サイズとか入ってる糞な処理系の存在を否定はしないけど普通の処理系ではポインタに入ってるのはアドレスだけだよ。それと別のところにも書いたけど「スマートポインタ」はただのクラスであってポインタなんかじゃないよ。 なーんて言ってるし、やっぱり件の記事と大差ないな。
Re: (スコア:0)
「FILE*はfopen()やfclose()の機能であってファイルハンドル管理とは無関係」
というわけか。
ハハハハハハハハ
Re:まぁ、驚いたのは (スコア:2, すばらしい洞察)
Javaが生まれたということはよく分かった。
優秀なエンジニア二人の手を止めてしまう訳か。
# お前らがポインタを知っている事はよく分かった。
# でも人に誤解しないように説明するスキルはそれと別だからな、ということ。
Re: (スコア:0)
学習してもC/C++のポインタ程度の事柄を理解できない人は、ポインタ以外の技術も理解できないと思う。
(大半のPGは技術を理解してる必要も無いんだけどね)
Re: (スコア:0, フレームのもと)
そういう結論に至った経緯に興味があるよ。書いてみ?
Re: (スコア:0)
この構造体のどこにポインタがでてくるの?
配列の識別子は、単体で表記する場合に、配列の先頭要素のアドレスと解釈されるという特例(&buff[0]の短縮表記)があるけど、
先頭アドレスのことをポインタと言ってるんじゃないよね?
ひょっとして、アドレスとポインタの区別が付いてない?
Re: (スコア:0)
>ひょっとして、アドレスとポインタの区別が付いてない?
つ【ブーメラン】
Re:まぁ、驚いたのは (スコア:1)
はしょりすぎて理解できなかったか?
Re: (スコア:0)
こらこら、嘘を書いちゃいかん。 自動的に const int *buff; みたいな変数宣言がされ、buffが buff[0]を指すように初期化されると思っていますか? そんな高度なことは、C/C++コンパイラはやりません。
表記が違うだけで、&buff[0]もbuffも同じものを表します。
もしかすると、あなたは *(buf+2) と buf[2] を違うものだと考えてたりしませんか?
Re:まぁ、驚いたのは (スコア:1)
Re: (スコア:0)
なるほど、sizeof(buf)のような時ですね。
C/C++の言語仕様そのものがすごくコンパクトに作られているのは認めますが、ミスを誘発するような仕様が幾つかあるのが残念ですね。
char s[20] = "hello world!";
なんて記述は、便利だけど酷い仕様です。
Re: (スコア:0)
これは酷い嘘。
「buffは&buff[0]を指すconstポインタ」ならば、&buffは、「&buff[0]を指すconstポインタ」のアドレスを返すとでも思ってるんでしょうか。
実在しないものは返せない。
ポインタとアドレスの区別をつけるのが、あなたの次のステップですね。
Re: (スコア:0)
たぶん、親コメを読んでないんでしょうが。
Re: (スコア:0)
あなたの言う「配列の先頭を指すconstポインタ」を指すポインタ変数を定義し、どのように使うのか見せてください。
Re: (スコア:0)
あなたの言う「配列の先頭を指すconstポインタ」に対して、sizeof演算子を実行したときの結果がどうなるか教えてください。
その理由も教えてね。
Re: (スコア:0)
Re: (スコア:0)
>
>あなたの言う「配列の先頭を指すconstポインタ」を指すポインタ変数を定義し、どのように使うのか見せてください。
あなたの要求する情報を格納する実メモリは存在しません。そんなコードを書くことは不可能です。
char c;
&cの値はcの格納されているアドレスを指すポインタですが、&cの値を格納しているメモリはありません。
&cがコード上に現れると、相対アドレスがコンパイル時のオフセット値を元に計算され、解決されます。
&c=NULL;といった代入はできないので、C言語の文法上、constポインタとして扱われます。
sizeof演算子はコンパイル時に解決されます。実行時解決はされません。
「実行」されてませんから質問の意味が不明です。
Re: (スコア:0)
>「実行」されてませんから質問の意味が不明です。
コンパイル時に解決されるか、ランタイム実行時に解決されるかは処理系依存です。
printf("%d\n", sizeof(buff)); の結果がどうなるかやってみ。
あなたの言うconstポインタとかいうもののサイズが分かるから。
Re: (スコア:0)
> &cの値はcの格納されているアドレスを指すポインタですが、&cの値を格納しているメモリはありません。
> &cがコード上に現れると、相対アドレスがコンパイル時のオフセット値を元に計算され、解決されます。
> &c=NULL;といった代入はできないので、C言語の文法上、constポインタとして扱われます。
&c の&は、"&演算子"です。&演算子は直後の変数のアドレスを取り出すという演算を行います。&cは、変数cのアドレスを求めるという演算です。
&cを、コンパイル時に相対アドレスとして解決する処
Re: (スコア:0)
>>「実行」されてませんから質問の意味が不明です。
>コンパイル時に解決されるか、ランタイム実行時に解決されるかは処理系依存です。
ちなみに、C99 では、文脈によっては(可変長配列)、必ず実行時解決になります。
Re: (スコア:0)
「(変数の)アドレスを指すポインタ」って理解すればいいです。
変数は変数でも記憶クラスがregisterだとポインタ使えないよ。
ポインタが指すのはあくまでもアドレス。
Re: (スコア:0)
うーん、動的に型定義できる言語とは聞いてたけど……
Re: (スコア:0)
レジスタ変数のアドレスを取得可能な処理系を使ったことがある。 register変数は必ず、CPUレジスタ上に置かねばならないという規約はないので、変数のアドレスをとるような処理がある場合はメモリ上にその変数の領域を確保するようにしていたようです。そもそもregisterという概念そのものがないCPUも存在するし、register変数をどのように実現するかは処理系依存だと思います。C言語の規約には、どのように動作するのが望ましいということが、書かれていそうです。
Re: (スコア:0)
register指定子は「可能ならレジスタに割り付ける」だけで、不可能なら単に無視されます。
register指定したにも関わらずメモリに割りついた変数のアドレスは取得できてもおかしくありません。
ただ、ソース上の指定がどうであれ、コンパイルの結果メモリに割り付けられたらレジスタ変数とは呼べません。
>register変数をどのように実現するかは処理系依存だと思います。
そもそもの話、メモリとレジスタをいかに活用するかはコンパイラの裁量ですよね。(volatileでない限り)
最適化次第では一旦メモリに割り付いた変数でもメモリに書き戻さず、レジスタ上で処理を続けたりするので
(記憶クラスが関数内で部分的に変化してる)もはやレジスタ変数という区分自体が意味を成さなくなってます。
#だからレジスタ変数という場合、純粋にレジスタに割り付く処理系が前提なのだと文脈で解釈して欲しい・・・