-
12-09-2019 - |
質問
Cできませんので使用のアドレスの登録変数はC++でいきます。なぜこの法律はC++がない。で誰か教えてくださいこのコンセプトで行います。
解決
こちらの抜粋から部6.7.1(脚注101)の C99標準(pdf):
この実装で処理他
register
宣言だとしてauto
宣言です。しかし、 るか否かの抗保管を実際に使用すると、アドレスの一部のオブジェクトを宣言した収納クラスの指定子を登録できない計算, は、明示的により使用の単項&
オペレーターとして議論6.5.3.2)または暗黙的により変換した配列名へのポインタとして議論6.3.2.1).このように、オペレーターに応用できる配列を宣言されて収納クラスの指定子register
はsizeof
.
から部7.1.1条第3項の規定に C++の標準(pdf):
A
register
指定子と同じ意味としてauto
指定子とヒントの実装は、オブジェクトで宣言されたすく使います。 【ご注意:のヒントでは無視され、ほとんどの実装では無視される場合のアドレスのオブジェクトが取得されます。末注意】
楽しい豆知識約 register
C++グループ(WG21) いdeprecate register
:
の
register
キーワードにしても機能は、あくまでヒントが合いは無視されます。で推奨されていません、このインテグレーションモジュースを解放reserved名まで利用では、将来の標準のようにauto
して再利用してこれを同様に絶対に無駄にはなりません。とから、2009年の会議:
の合意形成のCWGすることには賛成であdeprecating
register
.
なにが見える、C99グループ(WG14) 言 register
(pdf) 会:
一般的な合意をdeprecateの"
auto
"キーワードとなります。うお願いいたしまWG21に戻る 前の利用"register
"(住所)?いいえ、このことは飛WG21.
他のヒント
registerキーワードは単なるヒントであり、無視することができます。ほとんどのC ++コンパイラはその時間のすべてを無視しますが、C ++コンパイラは、変数のアドレスを取る場合は、それを無視する、またはそれへの参照を作成します。
一方、C ++コンパイラは無視しますが、変数のアドレスを取るという理由だけで「登録」するために、のHAVE のありません。理論的には、コンパイラは、(私の知っていること)レジスタに格納して、あなたに何とか舞台裏レジスタにマッピングされているいくつかの魔法のポインタ値を与えるが、それは非常に少ない利益のために多くの作業なので、ノーコンパイラだろう可能性そのようなものを行います。
レジスタは、同様にCで無視されますので、、私は、レジスタ変数のアドレスを取っに対する明示的な禁止は、このためにチェックする負担からCコンパイラを軽減するだけであったことを疑います。
C ++標準の関連部分は7.1.1.3である
レジスタ指定子はそう宣言されたオブジェクトが頻繁に使用されることが実装にヒントと一緒に自動指定と同じ意味を持っています。 [注:ヒントは無視することができ、オブジェクトのアドレスが取られている場合、ほとんどの実装では、それは無視されます。末端ノート]
スーパー後半の答えについては申し訳ありません。
問題がCで、register
は元々のみint
とchar
がそれのために使用することができる理由でレジスタに値を格納する意味する、ということです。しかし、時間と特に標準C ++で、それは「CPUのレジスタに」「高速アクセス」ではなくに拡大しました。
だから、C ++、多分register
タイプの配列ではなく、我々はCPUレジスタに配列を格納することはできないことを知っています。したがって、(上の意味での)C ++レジスタに対処するために、論理的に大丈夫ですが、値はCPUレジスタに実際にある場合は、まだ意味をなさないされます。
私はそれがCとの互換性がなかった場合、キーワードにも言語にそれを作っていないことを前提としています。私はどんな権威をもって話すことはできませんが、これはそうであるならば、単に標準の強制条項「コンパイラはあなたよりも賢いです」を超えて合法的にするための実用的な理由がある私には思える:C ++はせずに、物事のアドレスを取ります許可より容易にCが行うよりも。具体的には、次のメンバ関数、および参照。
メンバ関数は、暗黙のthis
パラメータを必要とするので、オブジェクトからそれらを呼び出すことは不可能であろうがregister
を宣言しました。 Cでは、register struct X x;
を言ってからあなたを禁止するものはありませんので、このような言語は、[C-互換性がキーワードでも存在する全体の理由があるため] C ++で許可されなければならないであろう。あなたはメンバ関数を呼び出すだけでなく、アドレスを服用禁止する場合でも、それはまた、最初のコンストラクタ呼び出しをカバーしています。本質的には、それが非PODのタイプでは動作しません。だから、すべての残りの部分は何のために使用することができたときに、法的な種類の小さなサブセットに対してのみ有効である一つの記憶クラス指定子で終わります。
また、このようなオブジェクトへの参照を作成できませんでした、にもかかわらず、技術的には、コンパイラはポインタとしての参照を処理する必要はありません。 register int i; int& x;
は二つの変数のためのスペースを持つことが必要ですが、後で行う場合は、&x
へのポインタで終わるi
されていません。だから、最初の構築物を違法にレンダリングする必要があります。参照が私達の前のポイントに戻って、とにかくCには存在しませんので、これは、非問題のように思えるが、register
指定子で宣言PODタイプはもはやコピーすることはできません。コンパイラが提供するコピーコンストラクタは、必要に応じて、フォームのX::X(const X&)
またはX::X(X&)
です。
ですから、Cとの互換性を維持するために、彼らはあなたができることを指定するには、[それはすべてのタイプに適用されないという点で、ストレージクラス指定子としてregister
を一意にすると、他の場所で標準の少なくとも2つの異なる部分を変更する必要があり] register
指定子で宣言された変数への参照を作成し、何とかPODのコピーのための参照を回避することはありません。それとも、彼らは単に「アドレスを取るために、その大丈夫」とコンパイラが要求を尊重するかどうかを決定しましょうと言うことができます。彼らはとにかくやっ上で計画していた何かます。
レジスタ変数がアドレスを持っていない、それがCPUレジスタに(少なくとも開催されることになっています)開催されています。レジスタ修飾子はヒントに過ぎないので、あなたはそれがアドレスだ抽出するためのコードを生成するようにコンパイラーに強制場合、修飾子は無視され、あなたはメモリに保存されている通常の変数になってしまいます。
直接1を使用すると、レジスタ変数のアドレスは(あなたのオリジナルのポスト自体が矛盾ます。..)あなたがあなた自身のヒントを無視して、少なくとも警告を発行する必要があります取ることができますどちらかあなたの質問に、答えるために。 IMO正しい実装は、レジスタ変数のアドレスを取得できないようになります。
覚えておくべき重要なことは、「登録」はコンパイラへの単なるヒントであるということです。 CおよびC ++は、両方のあなたの「アドバイス」を無視して、メモリ内の変数を維持するために許可されています。あなたは変数のアドレスを取る場合はもちろん、それはメモリのスポットを割り当てるためにそれを強制されます。
彼らは異なる言語であるため、CおよびC ++はちょうどあなたが何ができるかについて異なるルールを持っています。 C ++の設計者は、あなたはそれが何を傷つけることはありませんので、レジスタ変数のアドレスを取得できるようにすることを決めました。それはメモリにそれを強制するため、Cは、あなたがそれを行うことはできません。
それを考えるよりは、Cの制限は、変数は、それはそれは以降で使われているかに関係なく、それらに遭遇すると、変数のためのメモリをレイアウトすることができ、ブロックのコンパイラの冒頭で宣言されなければならなかったのと同じ理由で、おそらくです機能ます。
これが唯一の推測ですが、私は、このようなシンクタンクは、単に存在しないので、あなたがC ++でのレジスタのアドレスを取ることができることを疑います。 C ++は、おそらくあなたの特定のケースでレジスタを使用しません。ストレージクラス修飾子register
のみコンパイラへのヒントです(ほとんどのすべてではないが、現代のコンパイラは喜んでそれを完全に無視する)ことがわかります。
CとC ++は、大きな共通サブセットと、2つの異なる言語です。いくつかのものは、それらの間で異なっている理由です。
私はあなたの質問を理解していないものの、register
は、(少なくとも、C ++で)変数は、より頻繁にアクセスされる可能性があるというヒント、そして何よりもです。 Cでは、それはあなたが一度に意味の一定量を作っ&
単項演算子とアドレスを取ることができないことを意味します。 Cの初期の時代では、コンパイラは、変数のためのメモリを割り当てる気にしないかもしれない、と必ずしもそう取るべきアドレスがないことが予想された。
(コンピュータが正常にCPUのクイックアクセス部品であるレジスタ、ひいてはアクセスへの最速のストレージを持っている。それはより良いパフォーマンスを引き起こした場合、変数は、むしろメモリに比べて、レジスタに住んでいるかもしれません。)
今日では、ほぼすべてのコンパイラは、プログラマができるより良い自分の割り当てを行うのに十分洗練されているので、register
を使用すると、ほとんど常に無意味です。