IT이야기

NULL은 항상 false입니까?

cyworld 2022. 6. 9. 22:10
반응형

NULL은 항상 false입니까?

라고 가정해도 안전한가?NULLC에서는 항상 false로 변환됩니다.

void *somePtr = NULL;

if (!somePtr) {
  /* This will always be executed? */
}

또는 다음과 같은 값에 대해 명시적으로 확인해야 합니까?NULL만들어질까요?

네. NULL은 false로 평가됩니다.C는 0이 아닌 값을 true로 간주하고 제로 값은 false로 간주합니다.NULL은 기본적으로zeroaddress와 비교해서 취급되며, 부울체크를 위해 int로 승격될 것으로 생각합니다.당신의 코드는 C에 대해 잘 아는 사람이라면 누구나 읽을 수 있을 것이라고 생각합니다만, 체크는 분명히 하고 있을 것입니다.

C와 C++ 프로그래밍에서는 두 개의 늘 포인터가 동등함을 보증합니다; ANSI C는 정수형과의 비교에서 어떤 늘 포인터가 0과 같음을 보증합니다; 또한 매크로 NULL은 값 0으로 정의됩니다. 즉, 값 0(정수형 또는 포인터로 변환됨)으로 정의되므로, 늘 포인터는 비교됩니다.NULL과 동일합니다.

참고 자료: http://en.wikipedia.org/wiki/Null_pointer#Null_pointer

ISO/IEC 9899 복사:TC3 (2007년 9월 7일 위원회 초안)에서는 다음과 같이 기술되어 있습니다.

6.3 전환

1 여러 연산자가 피연산자 값을 한 유형에서 다른 유형으로 자동 변환합니다.

6.3.2.3 포인터

3 값이 0 [...]인 정수 상수 식을 늘 포인터 상수라고 합니다.늘 포인터 상수가 포인터 타입으로 변환되면 늘 포인터라고 불리는 결과 포인터는 오브젝트 또는 함수에 대한 포인터와 동등하지 않음을 보증합니다.

지금까지는 이해되요.ptr!=0모든 비표준에 대해 true(1)이다.ptr그러나 두 개의 늘 포인터가 어떻게 비교되는지, 아직 열려 있습니다.

6.5.9 등가 연산자

5 [...] 한 피연산자가 포인터이고 다른 피연산자가 null 포인터 상수인 경우 null 포인터 상수는 포인터 유형으로 변환됩니다.

6 두 개의 포인터가 동일한 경우 및 둘 다 null 포인터일 경우에만 [...]가 됩니다.]

이런 이유로,ptr==01(및ptr!=00)의 경우,ptr는 늘 포인터입니다.

6.5.3.3 1차 연산자

5 논리 부정 연산자 !의 결과는 피연산자의 값이 0과 동일하지 않으면 0, 피연산자의 값이 0과 동일하면 1이 됩니다.결과는 int 타입입니다.식!E는 (0==E)와 같습니다.

그래서 같은 것이 유효하다!ptr.

6.8.4.1 if 스테이트먼트

1 if 스테이트먼트의 제어식은 스칼라 타입을 가져야 한다.

2 두 형태 모두 식이 0과 동일하지 않을 경우 첫 번째 서브스테이트먼트가 실행된다.

스칼라 타입은 산술 타입 또는 포인터 타입입니다("6.2.5 타입", 조항 21 참조).종합하면 다음과 같습니다.

  • if (ptr)성공 »ptr!=01 µ이다ptr는 늘 포인터가 아닙니다.
  • if (!ptr)성공 »ptr==01 µ이다ptr는 늘 포인터입니다.

'C' 언어는 (void*)0이 실제로 유효한 포인터가 될 수 있는 시대로 거슬러 올라갑니다.8080 및 Z80 마이크로프로세서는 주소 0에 인터럽트 벡터를 가지고 있었습니다.이러한 아키텍처 선택에 직면하여 헤더 파일이 NULL 값을 선언하는 것 외에는 아무것도 할 수 없었습니다.NULL이 (void*)0과 같지 않은 컴파일러(0xffff가 다음 대안)가 되어 if() 문의 정의되지 않은 동작을 제공하는 컴파일러가 있었습니다.

C++는 다행히 이것을 종료합니다.늘 포인터는 0에서 할당이 가능하며 테스트도 가능합니다.

네.if(!p)가 유효하고 동작하고 있는 것이 보증됩니다.

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

https://port70.net/~nsz/c/c11/n1570.209 #6.3.2.3p3

즉,(void*)0는 늘 포인터입니다.그것은 또한 만약p그럼 포인터입니다.p==0와 동등하다p==(void*)0.

그것은 또한 만약p는 늘 포인터가 아닙니다.p==(void*)0평가하다0.

지금까지는 좋아.

null 포인터를 다른 포인터 유형으로 변환하면 해당 유형의 null 포인터가 생성됩니다.임의의 두 개의 늘 포인터는 동등하게 비교해야 한다.

http://port70.net/~nsz/c/c11/n1570.209 #6.3.2.3p4

"모든의 늘 포인터는 동등하게 비교해야 한다"는 점에 유의하십시오.즉, 만약p는 늘 포인터입니다.p==0평가의 정확성을 얻을 수 있습니다.왜냐하면0로 승진할 것이다.(void*)0이것은 늘 포인터입니다.또한 Null 이외의 포인터는 Null 포인터와 같을 수 없습니다.

부정 연산자를 볼까요?

논리 부정 연산자 !의 결과는 피연산자 값이 0과 동일하지 않으면 0, 피연산자 값이 0과 같으면 1이 됩니다.결과는 int 타입입니다.식!E는 (0==E)와 같습니다.

http://port70.net/~nsz/c/c11/n1570.209 #6.5.3.3p5

이것은 우리에게 말해준다!p와 같다p==0정의상, 이것은 와 같다.p==(void*)0상술한 바와 같이

그리고 모든 null 포인터가 동등하다는 사실을 고려하면, 이것은 다음을 의미합니다.p==(void*)0가 참이라고 평가할 수 있는 것은,p는 늘 포인터이며 false일 경우에만 해당됩니다.p는 늘 포인터가 아닙니다.

네, 그렇습니다.if(!p)안전한 방법으로 확인하실 수 있습니다.p는 늘 포인터인지 아닌지를 나타냅니다.

있음(적어도 표준 준거 C 컴파일러의 경우)

comp.lang.c FAQ:

Q: Null이 아닌 포인터를 테스트하기 위한 생략형 포인터 비교 "if(p)"는 유효한가요?null 포인터의 내부 표현이 0이 아니면 어떻게 됩니까?

A: 항상 유효합니다.

아무것도 추정하는 것은 결코 안전하지 않다.

또한 테스트 대상에 대한 명시적 확인도 더 명확합니다.

네, 그렇습니다.

C 표준 6.3.2.3

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

및 6.3.2.6

모든 포인터 유형을 정수 유형으로 변환할 수 있습니다.이전에 지정한 경우를 제외하고 결과는 구현 정의됩니다.결과를 정수 유형으로 나타낼 수 없는 경우 동작은 정의되지 않습니다.결과는 정수 유형의 값 범위 내에 있을 필요가 없습니다.

-

스칼라 값이 _Bool로 변환되면 값이 0과 같으면 0이 되고 그렇지 않으면 1이 됩니다.


NULL이란?

매크로 NULL은 <stdef>에 정의되어 있습니다.h>(및 기타 헤더)를 늘 포인터 상수로 합니다.


늘 포인터 상수 값은 얼마입니까?

이 0인 정수 상수 표현식 또는 void * 유형으로 주조된 표현식을 늘 포인터 상수라고 합니다.

정의 예:

#define NULL ((void*)0)


if(NULL) 평가

if ( expression ) statement

if ( expression ) statement else statement

In both forms, the first substatement is executed if the expression compares unequal to 0. In the else form, the second substatement is executed if the expression compares equal §6.8.4.1 Language 133 ISO/IEC 9899:TC3 Committee Draft — Septermber 7, 2007 WG14/N1256 to 0. If the first substatement is reached via a label, the second substatement is not executed.


So yes if the compiler is compliant with ISO C99 you can assume that the statement below will always execute.

if (!NULL) { statement; } 


Above quotations are from ISO/IEC 9899:1999 (C99). You can read it here.

NULL is just a preprocessor definition. It's in stdio.h. Typically, only an insane person would redefine it, but it's possible. An example:

#include <stdio.h>
#ifdef NULL
#undef NULL
#endif
#define NULL 1

void main()
{

        if (NULL)
                printf("NULL is true\n");
        else
                printf("NULL is false\n");
}

This code will print "NULL is true". Try it if you don't believe me. Your compiler might not even warn you that you're doing something weird.

Yes, mostly.

First off, NULL is a typedef. I could royally screw you over by saying in a previously included header

#define NULL 1

This might not make a lot of sense, but since when has other people's code ever made sense? :)

Also, while it's probably syntactically safe, it's not semantically correct. NULL means "nothing", neither true or false or a boolean value or int or string. It means "a symbol for nothing". So testing for NULL is more like a philisophical issue: If a tree falls in the forest, and if(listener), does it make a sound?

Do everyone a favor and be clear about testing against NULL.

NULL is defined as a constant pointer that is guaranteed to point to a useless/non-existent place in memory. Most implementations of NULL are ((void *)0) but it is not mandatory that this is so.

*NULL always targets to 0x00L. You can consider that false, but to be sure always do an explicit check.

According to me, it's not always safe to assume that. Since, depending on which headers have been included in a program, it can have been redefined. But according to the standard, the null pointer constant is guaranteed not to point to any real object and has a type void *.

우리의 경우 선언문은void *somePtr = NULL그럴 수도 있다void *somePtr = 0와 함께0null 포인터로 사용합니다.

"값이 0인 정수 상수 표현식 또는 void * 유형으로 주조된 표현식을 늘 포인터 상수라고 합니다.늘 포인터 상수가 포인터 타입으로 변환되면 늘 포인터라고 불리는 결과 포인터는 오브젝트 또는 함수에 대한 포인터와 동등하지 않음을 보증합니다." https://www.geeksforgeeks.org/few-bytes-on-null-pointer-in-c/

그 말은 간단히 말해서*somePtr거짓이 될 수 있습니다.

또 다른 참조는 NULL 포인터 상수에 대해 https://www.gnu.org/software/libc/manual/pdf/libc.pdf(944 A.3페이지)입니다.

언급URL : https://stackoverflow.com/questions/459743/is-null-always-false

반응형