((void*)0)이 null 포인터 상수입니까?
저는 이 블로그 게시물을 읽고 있으며 Null 포인터 상수 및 괄호로 묶인 표현 섹션 아래에서 저자는 ISO C 표준의 § 6.3.2.3 및 § 6.5.1을 참조하며 다음과 같이 말합니다.
괄호로 묶은 null 포인터 상수가 null 포인터 상수라고 말하지 않습니다.
그 말은, 엄밀히 말하면, 그건
(void*)0포인터 이지만 null은 null입니다.((void*)0)아닙니다.
그러면:
대부분의 C 구현은 괄호로 묶인 널 포인터 상수를 널 포인터 상수로 취급하고 정의합니다.
NULL둘 중 하나로서0,((void*)0)아니면 다른 방법으로.
두 개의 참조 섹션은 다음과 같습니다.
§ 6.3.2.3
값이 0인 정수 상수 식 또는 void * 유형으로 캐스팅된 식을 null 포인터 상수라고 합니다.
§ 6.5.1
괄호가 있는 표현식은 기본 표현식입니다.해당 유형 및 값은 괄호로 묶이지 않은 식의 유형 및 값과 동일합니다.괄호로 묶이지 않은 표현식이 각각 n값, 함수 지정자 또는 void 표현식이면 n값, 함수 지정자 또는 void 표현식입니다.
굵은 글씨의 문장은 다음과 같은 저자의 주장과 모순되지 않습니까?((void*)0)상수가 ?라는 메시지가 표시됩니다.
굵은 글씨의 문장은 다음과 같은 저자의 주장과 모순되지 않습니까?
((void*)0)상수가 ?라는 메시지가 표시됩니다.
아닙니다. (참고된 블로그가 제 것이기 때문에, 저는 약간 편향된 것을 인정합니다.)
굵은 글씨의 문장은 그 종류와 값이 괄호가 없는 표현의 것과 같다고 말합니다.이것만으로는 null 포인터 상수임을 암시하기에 충분하지 않습니다.
고려 사항:
void *var = 0;
(void*)0는 null 포인터 상수입니다. ((void*)0) 및 은 와유및값동일다니합과 .(void*)0.var 또한 의 유형 및 값이 동일합니다.(void*)0,그렇지만var분명히 null 포인터 상수가 아닙니다.
그렇다고는 해도, 99% 이상의 의도는((void*)0)는 null 포인터 상수이며, 보다 일반적으로 괄호로 묶은 null 포인터 상수입니다.표준 작성자들은 단지 그렇게 말하는 것을 무시했을 뿐입니다.그리고 6.5.1p5의 괄호로 묶인 표현식에 대한 설명은 괄호로 묶인 표현식에 의해 상속되는 몇 가지 다른 특성을 구체적으로 열거하고 있으므로,
괄호가 있는 표현식은 기본 표현식입니다.해당 유형 및 값은 괄호로 묶이지 않은 식의 유형 및 값과 동일합니다.괄호로 묶이지 않은 표현식이 각각 n값, 함수 지정자 또는 void 표현식이면 n값, 함수 지정자 또는 void 표현식입니다.
누락이 문제가 됩니다(다만 약간 그렇습니다).
하지만 논쟁을 위해, 가정해보자면,((void*)0)상수가 . " 는 null 포인터 상수입니다.그게 무슨 차이가 있습니까?
(void*)0상수이며, 이은 null 포인터 포인터입니다.void*로 묶은 표현의 의미론적 의미론적 의미론적 의미론적 의미론적 의미론적 의미론적 의미론적 의미론적 의미론적 의미론적 의미론적 의미론적 의미론적 의미론적 의미론적((void*)0) 은 포인터 형식의 null 있습니다.void*.둘다요.(void*)0그리고.((void*)0)주소 상수입니다. (글쎄요, 그런 것 같아요.)그렇다면 어떤 컨텍스트가 null 포인터 상수를 필요로 하고 주소 상수를 허용하지 않습니까?몇 개 밖에 없습니다.
6.5.9 동등한 연산자
포인터 될 수 (는 type의 될 수 .)void*그러나 함수 포인터는 null 포인터 상수가 아닌 경우에는 그렇지 않을 수 있습니다.)그래서 이것은:
void func(void);
if (func == ((void*)0)) { /* ... */ }
제약 조건 위반이 될 수 있습니다.
6.5.16.1 단순 할당
할당에서 null 포인터 상수는 포인터 대 함수 유형의 개체에 할당될 수 있으며 암시적으로 변환됩니다.의 표현식void* 포인터 . 포인터에는 수 . 함수 포인터에 할당되지 않을 수 있습니다.인수 전달 및 초기화에도 동일한 제약 조건이 적용됩니다.그래서 이것은:
void (*fp)(void) = ((void*)0);
다음과 같은 경우 제약 조건 위반이 됩니다.((void*)0)포인터 가 아닙니다. " 는 null 포인터 상수입니다.이것을 찾아주신 코멘트 hvd님께 감사드립니다.
공통 7.19 제3항<stddef.h>
매NULL는 "구현 정의 null 포인터 상수"로 확장됩니다.한다면((void*)0)상수가 다음과 같습니다. " " " null null " 입니다. 그러면 다음과 같습니다.
#define NULL ((void*)0)
무효가 됩니다.이것은 프로그래머가 아니라 구현에 부과되는 제한이 될 것입니다.참고:
#define NULL (void*)0
표준 헤더의 매크로 정의는 필요한 경우 괄호(7.1.2p5)로 완전히 보호되어야 하므로 절대적으로 유효하지 않습니다.한 표현인 괄가없으올바식을사수용있다습니할른면호▁the▁without다ion▁valid▁express니있습수es.sizeof NULL오류가 하여 구문오 일수있다로 됩니다. 다음으로 확장합니다.sizeof (void*)그 다음에 외부 상수가 나옵니다.0.
업데이트: 곧 출시될 2023년 ISO C 표준(C23)은 이 문제를 해결하고 다음 사항을 명확히 합니다.((void*)0)는 null 포인터 상수입니다.
N3054 초안 6.5.1 제5항은 다음과 같이 말하고 있습니다.
괄호가 있는 표현식은 기본 표현식입니다.해당 유형, 값 및 의미는 괄호로 묶이지 않은 식의 것과 동일합니다.
이것은 null 포인터 상수를 포함하는 괄호로 묶인 표현식이므로 의심할 여지 없이 null 포인터 값입니다.이 값을 r 값으로 사용하면 "준수" 버전을 r 값으로 사용하는 것과 정확히 동일한 효과를 얻을 수 있습니다.
null 포인터 상수만 허용할 수 있는 일부 구문 규칙이 있으면 적합하지 않습니다.하지만 저는 아무것도 모릅니다(C에 대해서는 덜 전문적이지만).
그리고 둘 다 상수가 아니지만(정식 문법 생성을 참조), null 포인터 상수와 주소 상수가 모두 허용되고 상수 null 포인터 값이 주소 상수 범주에 명시적으로 포함되기 때문에 이니셜라이저에서 둘 다 상수 식으로 나타날 수 있습니다.
포인터 비교는 또한 null 포인터 상수를 구체적으로 언급합니다...그러나 여기서는 포인터 값도 허용되며 모든 null 포인터 값이 동일하게 처리됩니다.3차 연산자와 할당 연산자도 동일합니다.
위의 표현식이 모두 유형의 상수 null 포인터 값인 C++에서는 이러한 규칙이 상당히 다르다는 것을 명심하십시오.void*그러나 범용 null 포인터 상수는 아닙니다.C++의 Null 포인터 상수는 0으로 계산되는 정수 상수 식입니다.그리고.void*은 다른 포인터 유형으로 암시적으로 변환되지 않습니다.
C 코드에서 아래 줄을 인쇄해 보십시오.
printf("%p", (void*)0);
출력은 다음과 같습니다.
(계속)
언급URL : https://stackoverflow.com/questions/26477209/is-void0-a-null-pointer-constant
'codememo' 카테고리의 다른 글
| Git: 모든 커밋을 제거하기 위해 원격 Git 저장소를 재설정하는 방법은 무엇입니까? (0) | 2023.07.17 |
|---|---|
| DataFrame의 문자열이지만 dtype은 개체입니다. (0) | 2023.07.17 |
| Python에서 Selenium WebDriver로 텍스트를 얻는 방법 (0) | 2023.07.17 |
| v-data-table Vuetify Vuex Axios API에서 API를 추가하는 방법 (0) | 2023.07.17 |
| EXTRACT() Hour(24시간 형식) (0) | 2023.07.17 |