[c++] `string.assign (string.data (), 5)`는 잘 정의되어 있습니까 아니면 UB입니까?

동료가 이것을 작성하고 싶었습니다.

std::string_view strip_whitespace(std::string_view sv);

std::string line = "hello  ";
line = strip_whitespace(line);

나는 돌아 오는 string_view것이 나에게 선험적으로 불편 하다고 말했고 , 더 나아가 여기의 앨리어싱은 UB처럼 보였다.

나는 line = strip_whitespace(line)이 경우에 해당 한다고 확신 할 수있다 line = std::string_view(line.data(), 5). 나는 전화 할 생각 string::operator=(const T&) [with T=string_view]에 해당하는 것으로 정의되는, line.assign(const T&) [with T=string_view]에 해당하는 것으로 정의된다, line.assign(line.data(), 5)이렇게 정의된다 :

Preconditions: [s, s + n) is a valid range.
Effects: Replaces the string controlled by *this with a copy of the range [s, s + n).
Returns: *this.

그러나 이것은 앨리어싱이 발생했을 때 어떤 일이 발생하는지 말하지 않습니다.

나는 어제 cpplang Slack 에서이 질문을하고 혼합 답변을 얻었습니다. 여기에서 권위있는 답변을 찾고 실제 라이브러리 공급 업체의 구현에 대한 경험적 분석을 찾으십시오.


내가 테스트 케이스를 작성 하기위한 string::assign, vector::assign, deque::assign, list::assign,와 forward_list::assign.

  • Libc ++는 이러한 모든 테스트 사례를 작동시킵니다.
  • Libstdc ++는 forward_listsegfaults를 제외하고 모두 작동 합니다.
  • MSVC 라이브러리에 대해 모르겠습니다.

libstdc ++의 segfault는 이것이 UB라는 희망을줍니다. 그러나 나는 libc ++과 libstdc ++가 적어도 일반적인 경우 에이 작업을 수행하기 위해 많은 노력을 기울이는 것을 보았습니다.



답변

assign문자열 에서 비 const 멤버 함수를 호출하면 ( …) 포인터에 […] 포인터 […]가 해당 요소 에 대해 무효화 됩니다. 이는 위반 전제 조건assign[s, s + n)이 정의되지 않은 동작하므로, 유효 범위입니다.

참고 string::operator=(string const&)자동 할당 무 조작하기 위해 특별히 언어가 있습니다.


답변