우리가 일반적으로 null이라 부르는 것에는 null character와 null pointer의 두종류가 있는데,
잘 구분해서 쓰는 것이 좋습니다.
null character : 내부의 모든 비트가 0인 byte
null pointer constant : 정수 0 혹은 void *형으로 형변환된 0
전자와 후자의 차이는, 그 내부표현에 있습니다.
전자는 그 내부표현이 모든 비트가 0인게 보장되지만 후자는 문법적으로만 0과 동일할 뿐 그 내부표현이 0일 필요는 없습니다.
사실 null pointer 뿐만 아니라 정수형과 포인터형 사이의 변환은 내부표현이 그대로 보존될 필요가 없습니다.
x86에 익숙한 사람들은 납득하지 못하는 부분이기도 한데,
실제로 오래된 구현체 중에는 그런 것들이 있었고,
C FAQ 같은 문서를 보면 그에 대한 여러가지 질문과 답변들이 수록되어 있습니다.
일반적으로 C에서 null pointer는 정수형과 서로 잘 상호변환되므로 섞어써도 이와 관련된 문제를 느끼기 힘들지만,
몇몇 주의해야 할 상황이 분명히 존재합니다.
예를 들자면 비원형 함수를 호출할 때나 가변인자 함수를 호출할 때입니다.
잘 알려진 사례는 unix에서 가변 인자 함수의 execl함수의 마지막 인자로 반드시 0이 아닌 NULL을 해야 하는 것인데,
NULL의 내부 표현이 0이 아닌 곳에서는 이걸 지키지 않으면 문제가 발생합니다.
위에서 인용하신 코드는 C++의 것인데,
C에서는 NULL을 implementation-defined인 값으로 정의하는 데 비해
C++은 void *형에서 다른 포인터 형으로의 암묵적인 형변환이 금지되므로 NULL을 그냥 0으로 정의합니다.
가져온 코드를 보면 상황에 따라 __null, ((void *)0), 0, 0LL등의 여러가지 방식으로 정의를 하지요?
어셈블리에 익숙한 사람들이 간과하는 문제는,
C 또한 고도로 추상화된 고급 언어라는 점입니다.
특정 구현체의 실제 동작에만 매몰되어서 원래의 정의와 의도를 찾아보는 걸 게을리하는 경우가 많은데,
원래의 정의를 찾아볼 생각은 안하고 그런 식으로 특정 구현체에서만 Try&Error로 학습하는건
되게 안좋은 버릇입니다.
되도록이면 권위있는 레퍼런스(제대로 된 책, 표준문서 등)를 찾아보는게 좋고,
하다못해 스택 오버플로우에서 검색어 때려보는 것만도 못합니다.
초기화에 주의하시기 바랍니다.
초기화에 주의하시기 바랍니다.
0x00 == NULL == '\0' 은 같습니다. (비트8개가 00000000 인것과 같습니다.)
이와는 다르게. 0 은 숫자. '0' "0" 문자 모두 다릅니다. ASCII 코드표를 참고하시기 바랍니다.
ZeroMemory() 는 범위가 정해지지 않았습니다.
memset() 은 구조체에 한해서 사용이 가능합니다. (클래스 사용시 오류가 있습니다.)
ST_ABC ABCStruct1 = { 2, }; 이 초기화 방법은 뒤에 값이 초기화 되지 않기도 하니. 주의하시기 바랍니다.
ABC 라는 구조체가 wingdi.h 에 이미 있으니. 같은 변수이름을 주의하시기 바랍니다.
자세한 내용은 MSDN 과 책을 참고해보시기 바랍니다.
----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.
매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.
각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com
...
> 0x00 == NULL == '\0' 은 같습니다. (비트8개가 00000000 인것과 같습니다.)
이분 NULL하고 NUL을 헷갈리시는 것 같군요. (헷갈리는 게 그것뿐이면 얼마나 다행이겠냐마는...)
stddef.h 에서는 0 이네요.
/* A null pointer constant. */
#if defined (_STDDEF_H) || defined (__need_NULL)
#undef NULL /* in case has defined it. */
#if defined(__GNUG__) && __GNUG__ >= 3
#define NULL __null
#else /* G++ */
#ifndef __cplusplus
#define NULL ((void *)0)
#else /* C++ */
#ifndef _WIN64
#define NULL 0
#else
#define NULL 0LL
#endif /* W64 */
#endif /* C++ */
#endif /* G++ */
#endif /* NULL not defined and or need NULL. */
#undef __need_NULL
----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.
매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.
각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com
우리가 일반적으로 null이라 부르는 것에는 null
우리가 일반적으로 null이라 부르는 것에는 null character와 null pointer의 두종류가 있는데,
잘 구분해서 쓰는 것이 좋습니다.
null character : 내부의 모든 비트가 0인 byte
null pointer constant : 정수 0 혹은 void *형으로 형변환된 0
전자와 후자의 차이는, 그 내부표현에 있습니다.
전자는 그 내부표현이 모든 비트가 0인게 보장되지만 후자는 문법적으로만 0과 동일할 뿐 그 내부표현이 0일 필요는 없습니다.
사실 null pointer 뿐만 아니라 정수형과 포인터형 사이의 변환은 내부표현이 그대로 보존될 필요가 없습니다.
x86에 익숙한 사람들은 납득하지 못하는 부분이기도 한데,
실제로 오래된 구현체 중에는 그런 것들이 있었고,
C FAQ 같은 문서를 보면 그에 대한 여러가지 질문과 답변들이 수록되어 있습니다.
일반적으로 C에서 null pointer는 정수형과 서로 잘 상호변환되므로 섞어써도 이와 관련된 문제를 느끼기 힘들지만,
몇몇 주의해야 할 상황이 분명히 존재합니다.
예를 들자면 비원형 함수를 호출할 때나 가변인자 함수를 호출할 때입니다.
잘 알려진 사례는 unix에서 가변 인자 함수의 execl함수의 마지막 인자로 반드시 0이 아닌 NULL을 해야 하는 것인데,
NULL의 내부 표현이 0이 아닌 곳에서는 이걸 지키지 않으면 문제가 발생합니다.
위에서 인용하신 코드는 C++의 것인데,
C에서는 NULL을 implementation-defined인 값으로 정의하는 데 비해
C++은 void *형에서 다른 포인터 형으로의 암묵적인 형변환이 금지되므로 NULL을 그냥 0으로 정의합니다.
가져온 코드를 보면 상황에 따라 __null, ((void *)0), 0, 0LL등의 여러가지 방식으로 정의를 하지요?
어셈블리에 익숙한 사람들이 간과하는 문제는,
C 또한 고도로 추상화된 고급 언어라는 점입니다.
특정 구현체의 실제 동작에만 매몰되어서 원래의 정의와 의도를 찾아보는 걸 게을리하는 경우가 많은데,
원래의 정의를 찾아볼 생각은 안하고 그런 식으로 특정 구현체에서만 Try&Error로 학습하는건
되게 안좋은 버릇입니다.
되도록이면 권위있는 레퍼런스(제대로 된 책, 표준문서 등)를 찾아보는게 좋고,
하다못해 스택 오버플로우에서 검색어 때려보는 것만도 못합니다.
댓글 달기