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 표준을 통해 검색을 수행했으며 배열을 "암시 적 수명 유형"으로 설명하는 항목을 찾지 못했습니다 (예 : 변형 검색). 귀하의 주장에 대한 자세한 설명을 제공하십시오 (예 : 표준의 섹션 및 조항). 관련 컨텍스트는 물론 소스를 찾을 수없이 질문에 대답하기가 어렵습니다.
피터

1
@Peter : eel.is/c++draft/basic.types#9 , 마지막 문장
geza

나는 PDF open-std.org/jtc1/sc22/wg21/docs/papers/2020/n4849.pdf ( 명백히 최신 작업 초안)를보고 있었고 그 문장조차 없습니다. "암시 적 수명"의 의미도 찾아야 할 것 같습니다. 귀하의 링크가 공개 초안으로 작성되지 않은 일부 "수정중인 수정 사항"을 선택했을 수 있습니다.
피터

1
@Peter 이번 변경은 P0593 이 최근 프라하 회의에서 표준으로 병합 된 결과입니다 . 아직 결과 초안을 공개하지는 않았지만 이 커밋에서 병합 된 문구 볼 수 있습니다 .
월넛

답변:


3

암시 적이 지 않은 수명 유형에 대한 배열을 암시 적으로 만들 수 있습니까?

예.

이러한 배열의 암시 적 생성으로 인해 배열 요소가 생성되지 않습니까?

예.

이것이 std::vector일반적인 C ++에서 구현 가능 하게 만드는 것입니다.


std::launder(static_cast<std::string*>(ptr))배열의 수명 내에 있지 않기 때문에 배열의 첫 번째 요소에 대한 포인터를 반환하지 않지만 배열이 수명 내에 있기 때문에 배열에 대한 포인터를 반환 한다는 것을 확인할 수 std::launder(static_cast<std::string(*)[10]>(ptr))있습니까?
올리 비

그것은 나에게 맞는 것 같습니다.
TC

@ Oliv 그리고 eel.is/c++draft/intro.object#11 은 이미 배열을 가리 키도록 보장 std::launder하기 때문에 실제로 필요하지 않다고 생각합니다 . ptr
호두

@ 호두, 나는 그것을 그리워했다. 소위 static_cast로하는 것은 std::string (*) [10]충분합니다! tx.
올리 비

@Oliv 그러나 질문은 std::launder의지가 없는 첫 번째 예제 가 잘 정의되어 있는지 여부가 됩니다. 지정할 std::string객체 는 없지만 ptr배열을 가리킬 수 있으므로 정적 캐스트는 값을 변경하지 않고 sptr배열을 가리 킵니다. 으로 std::launder그것은 단순히 때문에 UB이다 std::launder의 요구 사항.
호두
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.