development

C에서 NULL은 항상 0입니까?

big-blog 2020. 12. 30. 20:15
반응형

C에서 NULL은 항상 0입니까?


나는 어제 중간 수준의 소프트웨어 엔지니어링 직책을 맡은 사람과 인터뷰를했는데 그는 C에서 NULL이 항상 0이 아니며 NULL이 0이 아닌 C 구현을 보았다고 언급했습니다. 나는 이것이 매우 용의자라고 생각하지만 확신하고 싶습니다. 그가 옳은지 아는 사람 있나요?

(응답은이 후보자에 대한 내 판단에 영향을 미치지 않으며, 이미 내 관리자에게 내 결정을 제출했습니다.)


나는 당신이 널 포인터를 의미한다고 가정하고 있습니다. 과 비교하는 것이 보장됩니다 0. 1 그러나 모두 0 비트로 표시 할 필요는 없습니다. 2

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


  1. C99, 6.3.2.3을 참조하십시오.
  2. 명시적인 주장은 없습니다. 그러나 C99, 7.20.3에 대한 각주를 참조하십시오 (댓글의 @birryree 덕분에).

널 포인터 상수 는 항상 0입니다. NULL매크로는 구현에 의해 naked 0또는 캐스트 표현식 (void *) 0또는 기타 0 값 정수 표현식 (따라서 표준에서 "구현 정의"언어)으로 정의 될 수 있습니다.

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


§ C99 표준의 6.3.2.3에 따르면

값이 0 인 정수 상수 표현식 또는 void * 유형으로 캐스트 된 이러한 표현식을 널 포인터 상수라고합니다. 널 포인터 상수가 포인터 유형으로 변환되면 널 포인터라고하는 결과 포인터가 보장됩니다. 객체 나 함수에 대한 포인터와 같지 않음을 비교합니다.

§ 7.17은 또한 말합니다

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

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

(이것은 내가 지금 당장 가지고 있지 않은 이전 C 표준과 동일해야합니다)


C에는 프로그램이 올바르게 작동하기 위해 널 포인터 상수를 특정 포인터 유형으로 명시 적으로 캐스팅해야하는 컨텍스트가 하나뿐입니다. 해당 컨텍스트는 형식화되지 않은 함수 인수 목록을 통해 널 포인터를 전달합니다. 현대 C 에서는 가변 개수의 인수를받는 함수에 널 포인터를 전달해야하는 경우에만 발생합니다. (레거시 C에서는 프로토 타입으로 선언되지 않은 모든 함수에서 발생합니다.) 패러다임 예제는입니다 execl. 여기서 가장 마지막 인수는 다음으로 명시 적으로 캐스팅 된 null 포인터 여야합니다 (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 *있습니다 하지 형식화되지 않은 인수 목록을 통과 할 때 암시 적으로 상호 전환 그들이 다른 곳에 있더라도.

"후드", 여기에 문제는 없습니다 만 널 포인터에 사용되는 비트 패턴을하지만, 컴파일러가 제대로 호출 프레임을 설정하기 위해 각 인수의 정확한 구체적인 유형을 알아야 할 수 있음. 또한 어떤 ABI 위치를 고려 일부 ABI를 포인터 인수는 주소 레지스터에 있지만 데이터 레지스터에 인수 정수 전달 될 수 지정;. (그 별도의 주소와 데이터 레지스터과 함께 MC68000을 고려 int하고 void *같은 크기되지 않습니다 그리고 요즘 하고서, 드물지만. C는 여전히 명시 적으로 제공 않습니다 void *char *함수 프로토 타입이 있다면, 컴파일러가 사용할 수 있습니다). 같은 크기되지 않는,하지만 unprototyped 기능과 가변 인수는 그런 지원을 제공하지 않습니다.

C ++는 더 복잡하고 그 방법을 설명 할 자격이 없다고 생각합니다.


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

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

반응형