[c++] C ++ 20의 이후 런타임 결정에 따라 다른 암시 적 개체가있을 수 있습니까?

이 질문은 최신 C ++ 20 초안P0593 을 추가하는 것을 말합니다 .

내 예는 다음과 같습니다.

#include <cstdlib>
#include <cstdio>

void foo(void *p)
{
    if ( std::getchar() == 'i' )
    {
        *(int *)p = 2;
        std::printf("%d\n", *(int *)p);
    }
    else
    {
        *(float *)p = 2;
        std::printf("%f\n", *(float *)p);
    }
}

int main()
{
    void *a = std::malloc( sizeof(int) + sizeof(float) );
    if ( !a ) return EXIT_FAILURE;

    foo(a);
    // foo(a);    [2]
}

이 코드는 최신 초안의 모든 입력에 대해 잘 정의되어 있습니까?

P0593에 표현 된 이론적 근거 [2]는 두 사용자 입력 항목이 다를 경우 주석 처리를 제거 하면 엄격한 앨리어싱 위반으로 인해 정의되지 않은 동작이 발생할 수 있음을 상당히 명확하게합니다 . 암시 적 객체 생성은 malloc; 의 할당 문에 의해 트리거되지 않습니다 foo.

프로그램의 실제 실행에는 프로그램을 잘 정의 할 수있는 지정되지 않은 암시 적 개체 집합의 멤버가 있습니다. 그러나 [intro.object] / 10에 언급 된 암시 적 객체 생성을 선택해야하는지 명확하지 않습니다 malloc. 또는 결정이 “시간 여행”할 수 있는지 여부.

이진 블로 브를 버퍼로 읽어서 액세스하는 방법에 대한 런타임 결정을 내리는 프로그램 (예 : deserialization)에서 동일한 문제가 발생할 수 있습니다.



답변

암시 적 객체 생성은 malloc; 의 할당 문에 의해 트리거되지 않습니다 foo.

관련이 없습니다. 중요한 것은 어떤 객체가 생성되는지입니다. 표준에 따르면 생성되는 객체는 UB였던 것을 잘 정의 된 코드로 만드는 객체입니다.

이 작업은 프로그램이 동작을 정의했을 경우 지정된 저장 영역에서 0 개 이상의 암시 적 수명 유형 ([basic.types])의 수명을 암시 적으로 생성하고 시작합니다.

동작은 궁극적으로 정적 분석이 아닌 런타임 실행을 기반으로합니다. 따라서 동작이 정의되지 않은 경우가 발생하지만 해당 작업시 해당 스토리지에 특정 유형의 오브젝트가 작성된 경우 정의 될 때까지 프로그램 실행 만 수행하면됩니다.

따라서 생성 위치는 항상 “작업”이지만 생성되는 항목의 결정은 메모리가 런타임에 사용되는 방식 (예 : 동작)에 따라 결정됩니다.


답변