다음 코드는 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에서 정의되지 않은 동작을 가지고 있지 않습니다. 그러나 int
C 코드에서를 할당하고 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 ++ 표준에 정의되지 않은 동작입니다.