> 백엔드 개발 > C++ > 본문

C 정의되지 않은 동작에서 Null 포인터를 사용하여 정적 멤버에 액세스하고 있습니까?

Patricia Arquette
풀어 주다: 2024-11-01 18:24:02
원래의
368명이 탐색했습니다.

Is Accessing Static Members Using Null Pointers in C   Undefined Behavior?

C에서 Null 포인터를 사용하여 정적 멤버에 액세스

C에서는 일반적으로 초기화되지 않은 클래스 또는 구조체의 멤버에 액세스하는 것으로 이해됩니다. 포인터는 정의되지 않은 동작입니다. 그러나 정적 멤버는 특이한 예외를 보이는 것 같습니다. 다음 코드 조각은 이 동작을 보여줍니다.

<code class="cpp">#include <iostream>
class demo
{
    public:
        static void fun()
        {
            std::cout << "fun() is called\n";
        }
        static int a;
};
int demo::a = 9;
int main()
{
    demo *d = nullptr;
    d->fun();
    std::cout << d->a;
    return 0;
}</code>
로그인 후 복사

이 코드를 컴파일하고 실행하면 오류 없이 예상되는 출력("fun()이 호출됨" 및 "9")이 생성됩니다. 이는 질문을 제기합니다: 이 접근 방식에 어떤 해가 있습니까?

동작 이해

이 동작을 이해하려면 정적 멤버 액세스의 정의를 자세히 살펴보는 것이 중요합니다. C에서. 언어 표준에 따르면 정적 멤버에 액세스하는 데 사용되는 도트 연산자(.)는 본질적으로 null 포인터를 역참조한 다음 이 포인터가 가리키는 개체의 멤버에 액세스하는 것과 같습니다. 이 경우 널 포인터는 클래스의 인스턴스가 아닌 클래스의 정적 멤버를 참조합니다.

이는 널 포인터를 사용한 정적 멤버 액세스가 본질적으로 정의되지 않은 동작이 아닌 이유를 설명합니다. 중요한 측면은 *d 또는 d->a와 같은 액세스 표현식이 lvalue에서 rvalue로의 변환이나 초기화되지 않은 포인터를 처리할 때 일반적으로 정의되지 않은 동작을 트리거하는 기타 작업 없이 평가된다는 것입니다.

널 포인터를 통한 간접

그런 다음 질문이 생깁니다. 널 포인터를 통한 간접 참조는 항상 정의되지 않은 동작을 초래합니까? 대답은 놀랍게도 미묘합니다. 바로 이 주제를 다루는 공개 CWG 문제(#232)가 있으며, 널 포인터를 통한 간접 참조만으로는 정의되지 않은 동작을 구성하지 않는다는 데 합의가 있는 것 같습니다.

그러나 특정 경우에 유의하는 것이 중요합니다. lvalue가 rvalue로 변환되거나 비정적 멤버 함수가 null 포인터로 호출되는 경우와 같은 컨텍스트에서는 정의되지 않은 동작이 발생할 수 있습니다.

결론

결론적으로 널 포인터를 사용하여 정적 멤버에 액세스하는 것은 C에서 본질적으로 정의되지 않은 동작은 아니지만 주의해서 사용해야 합니다. 포인터를 처리할 때 정의되지 않은 동작을 유발할 수 있는 lvalue-rvalue 변환 및 기타 작업의 미묘함을 이해하는 것이 중요합니다.

위 내용은 C 정의되지 않은 동작에서 Null 포인터를 사용하여 정적 멤버에 액세스하고 있습니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!