>  기사  >  백엔드 개발  >  정의되지 않은 동작 없이 Null 포인터를 사용하여 C의 정적 멤버에 액세스할 수 있습니까?

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

Barbara Streisand
Barbara Streisand원래의
2024-11-02 11:53:03177검색

Can You Access Static Members in C   Using Null Pointers Without Undefined Behavior?

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

C에서는 정의되지 않은 동작을 호출하지 않고도 Null 포인터를 통해 클래스의 정적 멤버에 액세스할 수 있습니다. 놀랍게 보일 수 있는 이 동작은 언어의 정의와 이론적 근거를 검토하여 설명할 수 있습니다.

초기화되지 않은 포인터의 평가

널 포인터를 통해 클래스 멤버에 액세스할 때 동작은 잘- 피연산자의 평가에 지시 대상의 ID나 저장된 값이 필요하지 않은 한 정의됩니다. 예를 들어, 정적 멤버 변수 d->a에 액세스하면 *(d) 표현식을 평가하여 객체에 대한 참조를 얻을 뿐이지 참조 대상을 초기화해야 하는 작업은 수행하지 않습니다.

이 평가는 프로세스는 d->a가 ((d)).a로 변환됨을 나타내는 [expr.ref]/2에서 지원됩니다. *d로 표현되는 ((d))의 평가는 d가 참조하는 객체가 필요하지 않기 때문에 오류 없이 진행됩니다.

널 포인터와 정의되지 않은 동작을 통한 간접

C 표준에서는 널 포인터를 통한 간접 참조가 본질적으로 정의되지 않은 동작을 초래한다는 점을 명시적으로 명시하지 않습니다. 실제로 CWG 이슈 #232 및 #315에서는 단순한 간접 참조는 문제가 되지 않는다고 제안합니다.

이러한 입장에 대한 주요 주장은 널 포인터를 통한 간접 참조가 허용되는 잘 정의된 시나리오가 존재한다는 것입니다. 예를 들어, [expr.typeid]/2는 *d가 null로 평가되더라도 typeid(*((A*)0))가 bad_typeid 예외를 발생시키는 것을 허용합니다. 단순한 간접 참조가 UB를 호출한 경우 이 명령문은 잘 정의되지 않습니다.

프로그램에 대한 영향

귀하의 예에서

<code class="cpp">int main()
{
    demo* d = nullptr;
    d->fun();
    std::cout << d->a;
    return 0;
}</code>

프로그램은 UB 없이 컴파일되고 실행됩니다. 정적 멤버 함수를 호출하거나 정적 변수에 액세스하는 데는 참조 대상의 ID가 필요하지 않기 때문에 오류가 발생합니다. 따라서 귀하의 프로그램에는 고유한 문제나 정의되지 않은 동작이 없습니다.

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

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