C ++ 20以降、割り当てられたストレージでのポインター演算は許可されていますか?


10

C ++ 20標準では、配列型は暗黙の存続時間型であると言われています。

非暗黙的なライフタイムタイプの配列を暗黙的に作成できるということですか?このような配列を暗黙的に作成しても、配列の要素は作成されませんか?

このケースを考えてみます

//implicit creation of an array of std::string 
//but not the std::string elements:
void * ptr = operator new(sizeof (std::string) * 10);
//use launder to get a "pointer to object" (which object?)
std::string * sptr = std::launder(static_cast<std::string*>(ptr));
//pointer arithmetic on not created array elements well defined?
new (sptr+1) std::string("second element");

C ++ 20以降、このコードはUBではありませんか?


たぶんこの方法が良いですか?

//implicit creation of an array of std::string 
//but not the std::string elements:
void * ptr = operator new(sizeof (std::string) * 10);
//use launder to get a "pointer to the array of 10 std::string" 
std::string (* sptr)[10] = std::launder(static_cast<std::string(*)[10]>(ptr));
//pointer arithmetic on an array is well defined
new (*sptr+1) std::string("second element");

1
私は(ドラフト)C ++ 20標準を検索したところ、「暗黙的なライフタイムタイプ」として配列を説明するものは何も見つかりませんでした(そして、はい、バリエーションを検索しました)。あなたの主張のより詳細な説明を提供してください(例えば、規格のセクションと条項)。ソースを見つけることができず、関連するコンテキストはもちろんのこと、質問に答えるのは少し難しいです。
Peter

1
@ピーター:eel.is/c++draft/basic.types#9、最後の文
ゲザ

私はPDF open-std.org/jtc1/sc22/wg21/docs/papers/2020/n4849.pdfおそらく最新の草案)を見ていましたが、その文すらありません。「暗黙の寿命」の意味も見つける必要があるようです。あなたのリンクは、リリースされたワーキングドラフトにさえ至っていないいくつかの「進行中の編集」を拾ったのではないかと思います。
Peter

1
@Peter変更は、P0593が最近のプラハ会議の標準にマージされた結果です。結果のドラフトはまだリリースされていませんが、このコミットでマージされた表現確認できます。
クルミ

回答:


3

非暗黙のライフタイムタイプの配列を暗黙的に作成できるということですか?

はい。

このような配列を暗黙的に作成しても、配列の要素は作成されませんか?

はい。

これはstd::vector、通常のC ++で実装可能にするものです。


std::launder(static_cast<std::string*>(ptr))それがその存続期間内ではないため、配列の最初の要素へのポインタを返さないが、配列が存続期間内であるため、配列へのポインタを返すことも確認できますstd::launder(static_cast<std::string(*)[10]>(ptr))か?
Oliv

それは私には正しいようです。
TC

@Olivそしてstd::laundereel.is / c ++ draft / intro.object#11ptrはすでに配列を指すことを保証しているので、実際には必要ではないと思いますか?
クルミ

@ウォールナット、私はそれを逃した。したがって、static_castto std::string (*) [10]で十分です。tx。
Oliv

@Olivしかし、問題はおそらく、最初の例がなしでstd::launder明確になるかどうかです。std::string指すオブジェクトはありませんがptr、配列を指すことができるため、静的キャストは値を変更せずsptrに配列も指すようにします。std::launderそれだけで理由のUBでstd::launderの要件。
クルミ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.