경고 C26449
gsl::span
또는std::string_view
임시에서 만든 것은 임시가 무효화될 때 유효하지 않습니다(gsl.view).
C++ 핵심 지침: GSL.view: 뷰.
범위 및 보기는 메모리 버퍼를 참조할 수 있는 편리하고 간단한 형식입니다. 그러나 신중하게 사용해야 합니다. 인터페이스는 표준 컨테이너와 비슷하지만 해당 동작은 포인터 및 참조의 동작과 비슷합니다. 데이터를 소유하지 않으며 임시 버퍼에서 생성해서는 안 됩니다. 이 검사 원본 데이터가 일시적이지만 범위 또는 뷰는 그렇지 않은 경우에 중점을 둡니다. 이 규칙은 레거시 코드가 현대화되고 범위 또는 뷰를 채택할 때 수행되는 미묘하지만 위험한 실수를 방지하는 데 도움이 될 수 있습니다. 범위 참조와 관련된 약간 다른 시나리오를 처리하는 또 다른 검사 있습니다. C26445 NO_SPAN_REF.
C26815 및 C26816을 사용하는 것이 좋습니다. 이러한 경고는 이 경고의 더 일반적인 버전입니다.
설명
이 규칙은 생성자가 범위 또는 뷰에 대해 호출되고 원본 데이터 버퍼가 동일한 문에서 만든 임시 개체에 속하는 위치에 대해 경고합니다. 이 검사 포함됩니다.
- 반환 문의 암시적 변환;
- 3항 연산자에서 암시적 변환;
- 식의
static_cast
명시적 변환; - 값으로 컨테이너를 반환하는 함수 호출입니다.
함수 호출 인수에 대해 만들어진 임시 항목은 플래그가 지정되지 않습니다. 대상 함수가 외부 변수에 데이터 포인터를 유지하지 않는 경우 이러한 임시에서 범위를 전달하는 것이 안전합니다.
범위 또는 뷰 자체가 임시인 경우 규칙은 건너뜁니다.
검사er의 데이터 추적에는 특정 제한 사항이 있으므로 여러 개 또는 모호한 재할당과 관련된 복잡한 시나리오는 처리되지 않을 수 있습니다.
코드 분석 이름: NO_SPAN_FROM_TEMPORARY
예시
결과 형식의 미묘한 차이:
// Returns a predefined collection. Keeps data alive.
gsl::span<const sequence_item> get_seed_sequence() noexcept;
// Returns a generated collection. Doesn't own new data.
std::vector<sequence_item> get_next_sequence(gsl::span<const sequence_item>);
void run_batch()
{
auto sequence = get_seed_sequence();
while (send(sequence))
{
sequence = get_next_sequence(sequence); // C26449
// ...
}
}
이 문제를 해결하려면 뷰 자체가 있는 이상에 있는 개체에서 뷰가 만들어지도록 합니다. 경우에 따라 데이터를 복사하여 솔루션을 달성할 수 있으며, 임시 복사본을 반환하는 대신 오래 지속되는 개체에 대한 참조를 공유하도록 일부 API를 다시 디자인해야 하는 경우도 있습니다.