[解決済み] C++17以降も正しいアドレスと型を持つポインタは常に有効なポインタなのか?
質問
<サブ (参考として この質問と回答 .)
C++17 標準以前は、次のような文が [基本.複合]/3 :
<ブロッククオートT型のオブジェクトがアドレスAにある場合、アドレスAを値とするcv T*型のポインタは、その値がどのように得られたかに関わらず、そのオブジェクトを指すとされる。
しかし、C++17 からは、この文は が削除されました。 .
例えば私は、この文章によってこの例のコードが定義され、C++17以降ではこれが未定義の動作になっていると考えています。
alignas(int) unsigned char buffer[2*sizeof(int)];
auto p1=new(buffer) int{};
auto p2=new(p1+1) int{};
*(p1+1)=10;
C++17以前は
p1+1
へのアドレスを保持します。
*p2
へのアドレスを持ち、正しい型を持っているので
*(p1+1)
へのポインタです。
*p2
. C++17では
p1+1
は
末尾のポインタ
であるため
オブジェクトへのポインタ
であり、再参照はできないと思っています。
この規格の修正の解釈は正しいのでしょうか、それとも引用文の削除を補う他のルールがあるのでしょうか。
どのように解決するのですか?
この規格の修正の解釈は正しいのでしょうか、それともこの引用文の削除を補う他のルールがあるのでしょうか。
はい、この解釈は正しいです。末尾を過ぎたポインターは、たまたまそのアドレスを指している別のポインター値に単純に変換できるわけではありません。
新しい [基本.複合]/3 は言う。
ポインタ型のすべての値は、以下のいずれかです。
(3.1) オブジェクトまたは関数へのポインタ(ポインタはオブジェクトまたは関数を指すとされる)、または
(3.2) オブジェクトの終わりを過ぎたポインタ([expr.add])、または
これらは相互に排他的です。
p1+1
は終わりを過ぎたポインタであり、オブジェクトへのポインタではありません。
p1+1
を指すのは、仮想的な
x[1]
にあるサイズ1の配列の
p1
になるのではなく
p2
. これらの2つのオブジェクトはポインタ相互変換可能ではありません。
また、非典型的な注釈もあります。
[ 注意: オブジェクトの末尾を過ぎたポインタ ([expr.add]) は、そのアドレスにあるかもしれない、そのオブジェクトの型の無関係なオブジェクトを指しているとは見なされません。[...]
であり、これは意図を明確にしています。
T.C.が多数のコメントで指摘しているように、(
特にこれ
を実装しようとしたときに起こる問題の特殊なケースです。
std::vector
- を実装しようとしたときに起こる問題で、それは
[v.data(), v.data() + v.size())
は有効な範囲である必要があり、なおかつ
vector
は配列オブジェクトを生成しないので、唯一定義されたポインタ演算は、ベクトル内の任意のオブジェクトから、その仮想的な1サイズの配列の最後を過ぎて行くことでしょう。より多くのリソースについては
CWG 2182
,
この標準的な議論
と、2つの論文のリビジョンがあります。
P0593R0
と
P0593R1
(特に1.3項)を参照してください。
関連
-
[解決済み】C-stringを使用すると警告が表示される。"ローカル変数に関連するスタックメモリのアドレスが返される"
-
[解決済み】「corrupted size vs. prev_size」glibc エラーを理解する。
-
[解決済み】クラステンプレートの使用にはテンプレート引数リストが必要です
-
[解決済み] [Solved] インクルードファイルが開けません。'stdio.h' - Visual Studio Community 2017 - C++ Error
-
[解決済み] 数値定数の前にunqualified-idを付けて、数値を定義することを期待する。
-
[解決済み】変数やフィールドがvoid宣言されている
-
[解決済み] 型名の後の括弧は、newで違いがあるのでしょうか?
-
[解決済み】f(i = -1, i = -1)の挙動が未定義なのはなぜ?
-
[解決済み] C++17でi = i++ + 1;が合法になったのはなぜですか?
-
[解決済み] ヌルポインタのアドレスはなぜゼロなのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】識別子 "string "は未定義?
-
[解決済み】C++ - 解放されるポインタが割り当てられていないエラー
-
[解決済み] string does not name a type Errorが発生するのはなぜですか?
-
[解決済み】#include<iostream>は存在するのですが、「識別子 "cout "は未定義です」というエラーが出ます。なぜですか?
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
-
[解決済み】標準ライブラリにstd::endlに相当するタブはあるか?
-
[解決済み】クラスのコンストラクタへの未定義参照、.cppファイルの修正も含む
-
[解決済み】VC++の致命的なエラーLNK1168:書き込みのためにfilename.exeを開くことができません。
-
[解決済み】Visual Studioのデバッガーエラー。プログラムを開始できません 指定されたファイルが見つかりません
-
[解決済み] スタックアロケーションにより初期化されていない値が作成された