>백엔드 개발 >C++ >C 객체를 자체 생성자에 전달하는 것이 합법적입니까?

C 객체를 자체 생성자에 전달하는 것이 합법적입니까?

Patricia Arquette
Patricia Arquette원래의
2024-11-13 10:13:02750검색

Is it legal to pass a C   object into its own constructor?

C 객체를 자체 생성자에 전달하는 것이 합법적인가요?

다음과 같은 코드가 작동하는 것처럼 보이는 것은 당혹스럽습니다.

#include <iostream>

struct Foo {
    Foo(Foo& bar) {
        std::cout << &bar << std::endl;
    }
};

int main(int argc, char** argv) {
    Foo foo(foo); // I can't believe this works...
    std::cout << &foo << std::endl; // but it does...
    return 0;
}

초기화되지 않은 객체의 주소를 자체 생성자에 전달함으로써 우리는 다음과 같이 보입니다. 순환적 정의를 확립합니다. 질문이 생깁니다. 표준에서는 객체를 생성하기 전에 함수에 객체를 전달하는 것을 허용합니까? 아니면 이것이 정의되지 않은 동작에 해당합니까?

합법적이지만 드문 일이 아닙니다

초기화되지 않은 객체의 주소를 자체 생성자에 전달하는 것은 정의되지 않은 동작이 아닙니다. foo가 초기화되지 않은 동안 표준 승인 방식으로 사용합니다.

초기화가 완료되기 전에 개체 메모리 할당이 발생합니다. 결과적으로, 이 간격 동안 해당 변수에 대한 참조를 바인딩하고 해당 주소를 검색하는 것이 허용됩니다.

이 동작은 이러한 상황에서 생성된 참조가 유효한 것으로 간주됨을 명시하는 결함 보고서 363에 부합합니다. C 14 표준의 섹션 3.8 [basic.life]에서는 할당되었지만 초기화되지 않은 객체를 참조하는 glvalue를 사용하는 것이 제한 내에서 허용된다고 명시합니다.

즉, lvalue-to-rvalue 변환을 적용할 수 없으며 비정적 액세스가 가능합니다. 데이터 멤버, 비정적 멤버 함수 호출, 가상 기본 클래스 참조에 바인딩, Dynamic_cast 또는 typeid 사용.

이 예에서는 다음을 피합니다. 이러한 금지된 행위는 참조를 바인딩하고 주소를 획득하는 것입니다.

컴파일러 경고

행동의 적법성에도 불구하고 Clang은 경고를 발행합니다.

warning: variable 'foo' is uninitialized when used within its own initialization [-Wuninitialized]

초기화되지 않은 자동 변수에서 불확실한 값이 생성되면 정의되지 않은 동작을 구성하므로 이 경고는 타당합니다. 그럼에도 불구하고 우리의 사용은 불확실한 값을 산출하지 않으므로 합법적입니다.

추가 고려 사항

객체를 자체 생성자에 전달하여 자체 초기화하는 것은 본질적으로 아닙니다. 유익하거나 바람직하다면 이는 학급 행동을 탐구하는 흥미로운 방법이 될 수 있습니다. 그러나 int x = x;와 같은 할당을 통한 자체 초기화는 정의되지 않은 동작을 구성합니다.

위 내용은 C 객체를 자체 생성자에 전달하는 것이 합법적입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.