[c++] C ++ 20까지 int 정의되지 않은 동작에 malloc을 사용하고 있습니다.

다음 코드는 C ++ 20까지 정의되지 않은 동작이 있다고 들었습니다.

int *p = (int*)malloc(sizeof(int));
*p = 10;

사실인가요?

인수는 int값을 할당하기 전에 객체 의 수명이 시작되지 않는다는 것입니다 ( P0593R6 ). 문제를 해결하려면 배치를 new사용해야합니다.

int *p = (int*)malloc(sizeof(int));
new (p) int;
*p = 10;

개체의 수명을 시작하기 위해 간단한 기본 생성자를 호출해야합니까?

동시에 코드는 순수 C에서 정의되지 않은 동작을 가지고 있지 않습니다. 그러나 intC 코드에서를 할당하고 C ++ 코드에서 사용하면 어떻게 될까요?

// C source code:
int *alloc_int(void)
{
    int *p = (int*)malloc(sizeof(int));
    *p = 10;
    return p;
}

// C++ source code:
extern "C" int *alloc_int(void);

auto p = alloc_int();
*p = 20;

여전히 정의되지 않은 동작입니까?



답변

사실인가요?

예. 기술적으로 말하면 다음의 일부가 아닙니다.

int *p = (int*)malloc(sizeof(int));

실제로 유형의 객체를 생성 int하므로 p실제가 없기 때문에 역 참조 는 UB int입니다.

객체의 수명을 시작하기 위해 사소한 기본 생성자를 호출해야합니까?

당신이 할 에이 정의되지 않은 동작이 사전 C ++ (20)을 방지하기 위해 C ++ 객체 모델 당? 예. 이 작업을 수행하지 않으면 실제로 컴파일러가 해를 입힐 수 있습니까? 내가 아는 것은 아닙니다.

[…] 여전히 정의되지 않은 동작입니까?

예. C ++ 20 이전 버전에서는 실제로 int어디에도 객체를 생성하지 않았 으므로 이것은 UB입니다.


답변

네, UB였습니다. int존재할 수 있는 방법의 목록 이 열거되었으며 malloc이 인과 적이라고 생각하지 않는 한 거기에는 적용되지 않습니다.

이는 표준의 결함으로 널리 간주되었지만 그 특정 비트에 대한 C ++ 컴파일러가 수행 한 최적화가 해당 사용 사례에 문제를 일으키지 않았기 때문에 중요도가 낮습니다.

두 번째 질문에 대해 C ++는 C ++와 C가 상호 작용하는 방식을 요구하지 않습니다. 따라서 C와의 모든 상호 작용은 … UB, 일명 C ++ 표준에 정의되지 않은 동작입니다.


답변