programing

C의 NULL은 항상 0입니까?

goodcopy 2022. 7. 26. 22:31
반응형

C의 NULL은 항상 0입니까?

어제 미드레벨의 소프트웨어 엔지니어링 담당자와 인터뷰를 했는데, 그는 C에서 NULL이 항상 제로인 것은 아니며, NULL이 0이 아닌 C의 구현을 본 적이 있다고 말했습니다.매우 의심스럽긴 하지만 확실히 하고 싶군요.그가 옳은지 아는 사람?

(이 후보자에 대한 제 판단에는 아무런 영향이 없습니다.저는 이미 제 결정을 매니저에게 제출했습니다.)

내 생각엔 넌 늘 포인터를 말하는 것 같은데.될 수 있습니다.0단,2 반드시 0비트로 표시할 필요는 없습니다.1

포인터에 대한 comp.lang.c FAQ도 참조하십시오.


  1. C99, 6.3.2.3 참조.
  2. 명확한 주장은 없지만 C99, 7.20.3의 각주를 참조하십시오(댓글의 @birryree 덕분에).

C에는 프로그램이 올바르게 동작하기 위해 특정 포인터 타입에 눌 포인터 상수를 명시적으로 캐스트할 필요가 있는 컨텍스트가 하나밖에 없습니다.해당 컨텍스트는 입력되지 않은 함수 인수 목록을 통해 늘포인터를 전달하고 있습니다현대 C에서는 변수 개수의 인수를 사용하는 함수에 늘포인터를 전달할 필요가 있는 경우에만 발생합니다.(레거시 C에서는 시제품으로 선언되지 않은 함수에서 발생합니다.)패러다임의 예는 입니다.여기서 마지막 인수는 명시적으로 캐스트된 늘포인터여야 합니다(char *):

execl("/bin/ls", "ls", "-l", (char *)0);    // correct
execl("/bin/ls", "ls", "-l", (char *)NULL); // correct, but unnecessarily verbose

execl("/bin/ls", "ls", "-l", 0);            // undefined behavior
execl("/bin/ls", "ls", "-l", NULL);         // ALSO undefined behavior

네, 마지막 예에서는 다음과 같은 경우에도 정의되지 않은 동작이 있습니다. NULL되어 있습니다.((void *)0), 냐냐void * ★★★★★★★★★★★★★★★★★」char *다른 모든 곳에 존재하더라도 타입이 지정되지 않은 인수 목록을 통과하면 암묵적으로 상호 변환되지 않습니다.(C2011에는 통과 시 암묵적으로 상호 변환이 가능하도록 하는 언어가 있습니다.va_arg, 함수가 인수를 하여 variadic 인수에 하도록 지정하는 것을 va_arg따라서 프로그램의 일부인 가변 함수에만 의존할 수 있습니다.DR을 실행하다)

여기서의 문제는 늘 포인터에 사용되는 비트 패턴뿐만 아니라 컴파일러가 콜프레임을 올바르게 설정하기 위해 각 인수의 정확한 유형을 알아야 한다는 것입니다.(MC68000을 고려하세요.주소와 데이터 레지스터를 가진 일부 ABI는 포인터 인수를 주소 레지스트리에 전달하도록 지정했습니다.데이터 레지스터에 정수 인수가 포함되어 있습니다.또한 ABI를 고려해 주십시오.int그리고.void *같은 사이즈가 아닙니다.그리고 지금은 매우 드물지만, C는 여전히 분명히 같은 크기를 제공하고 있지 않습니다.[편집: 확실하지는 않지만 더 이상 허용되지 않을 수 있습니다.) 함수의 프로토타입이 있는 경우 컴파일러는 사용할 수 있지만, 프로토타입이 없는 함수와 변수에는 이러한 지원이 제공되지 않습니다.

C++는 더 복잡해서 어떻게 설명해야 할지 모르겠다.

§ C99 표준의 6.3.2.3은 다음과 같이 말한다.

값이 0인 정수 상수 표현식 또는 void* 타입으로 주조된 표현식을 늘 포인터 상수라고 합니다). 늘 포인터 상수가 포인터 유형으로 변환되면 늘 포인터라고 불리는 결과 포인터는 객체 또는 함수에 대한 포인터와 동등하지 않음을 보증합니다.

§ 7.17도 다음과 같이 말한다.

[...] 구현 정의 Null 포인터 상수로 확장되는 NULL [...]

NULL 포인터의 주소는 0과 다를 수 있지만 대부분의 경우처럼 작동합니다.

(이 방법은 오래된 C 규격과 동일해야 합니다만, 지금은 가지고 있지 않습니다.)

포인터 상수는 항상 0입니다.NULL를 네이키드()로 할 수 .0 깁스 , 예를 들어 깁스 예를 들어 깁스 표현,(void *) 0또는 기타 제로값 정수식(표준에서 "정보 정의" 언어 포함)을 지정합니다.

null 포인터 값은 0 이외의 값일 수 있습니다.늘 포인터 상수가 발견되면 적절한 늘 포인터 값으로 변환됩니다.

일부 구현에서는 포인터의 크기가 정수의 크기와 같지 않습니다.정수 컨텍스트의 NULL은 0이지만 실제 이진 레이아웃이 모두 0일 필요는 없습니다.

언급URL : https://stackoverflow.com/questions/9894013/is-null-always-zero-in-c

반응형