2013-04-23 1 views
3

다음 코드 바보 :nullptr은 C++에서 정의되지 않은 동작을 참조합니까? <code>nullptr</code> 포인터와 참조하여 주위

#include <cstdio> 

void printRefAddr(int &ref) { 
    printf("printAddr %p\n", &ref); 
} 

int main() {  
    int *ip = nullptr; 
    int &ir = *ip; 

    // 1. get address of nullptr reference 
    printf("ip=%p &ir=%p\n", ip, &ir); 

    // 2. dereference a nullptr pointer and pass it as reference 
    printRefAddr(*ip); 

    // 3. pass nullptr reference 
    printRefAddr(ir); 

    return 0; 
} 

질문는 : C++ 표준에서 문을 1..3 유효한 코드 또는 정의되지 않은 동작을 주석?

다른 버전의 C++에서 이전 버전과 동일하거나 다른가요? (예 : 물론 nullptr 키워드 대신 0 리터럴을 사용 하시겠습니까?)

보너스 질문 : 실제로 위의 코드가 예상치 못한/충돌을 일으키는 컴파일러/최적화 옵션이 있습니까? 예를 들어 *ptr에서 참조 인수를 전달하는 것을 포함하여 참조가 초기화되는 모든 곳의 nullptr에 대한 암시 적 어설 션을 생성하는 모든 컴파일러에 대한 플래그가 있습니까?


예상치 못한 호기심, 아무것도 예 출력 :

ip=(nil) &ir=(nil) 
printAddr (nil) 
printAddr (nil) 
+0

null 포인터 참조는 항상 UB였습니다. 너 찾았 니? – sehe

+3

'ip '를 최초로 참조 할 때 이미 UB 방식 (1)을 사용하고 있습니다. – Xeo

답변

6

// 2. dereference a nullptr pointer and pass it as reference

널 포인터를 역 참조는 정의되지 않은 행동이며, 그래서 여부 당신이로 전달 참조 또는 값에 의해, 당신이 그것을 역 참조 했으므로 UB를 호출했습니다. 모든 베팅에서 그 시점의 g는 꺼져 있습니다.

이미 여기 UB를 호출했습니다 ir 이후

int &ir = *ip; //ip is null, you cannot deref it without invoking UB. 
1

는 자체에 정의되지 않은 동작이 발생하지 않습니다 *ip 단지 그림자입니다.

정의되지 않은 동작은 nullptr_t을 가리키는 포인터를 사용하고 있습니다. *ip을 사용한다는 의미입니다. 따라서

int &ir = *ip; 
      ^^^ 

UB가 발생합니다.