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 중국어 웹사이트의 기타 관련 기사를 참조하세요!