(void) 0이 C와 C++에서 작동하지 않는 이유는?
내부적으로 다음과 같이 정의된 glibc에서 디버그 인쇄fs를 본 적이 있다.(void) 0
, NDEBUG가 정의된 경우.마찬가지로 비주얼 C++ 컴파일러도 거기에 있다.전자는 GCC와 VC++ 컴파일러 모두에서 작동하며, 후자는 VC++에서만 작동한다.이제 우리 모두는 위의 두 진술이 모두 아무런 조작도 없고 각각의 코드가 생성되지 않을 것이라는 것을 알고 있다. 하지만 여기서 나는 의심이 간다.
의 경우__noop
MSDN은 그것이 컴파일러에 의해 제공되는 본질적인 함수라고 말한다.로 오는 중(void) 0
왜 컴파일러에 의해 수술을 하지 않는 것으로 해석되는가?C언어를 까다롭게 사용하는 것인가, 아니면 표준이 그것을 탐구적으로 말하는 것인가?아니면 그것조차 컴파일러 구현과 관련이 있는가?
(void)0
(+;
'도 하지 않는'은 타당하지만 '아무것도 안하는' C++ 표현, 그것이 전부다.로 번역되지 않는다.no-op
대상 아키텍처의 지시, 언어가 완전한 문(예: 점프 라벨의 표적 또는 본문)을 기대할 때마다 자리 표시자로 빈 문일 뿐이다.if
절이다.
편집: (Chris Lutz의 코멘트를 기반으로 업데이트됨)
매크로로 사용할 때는 다음과 같이 해야 한다.
#define noop ((void)0)
그(void)
그것이 우연히 다음과 같은 가치로 사용되는 것을 방지하다.
int x = noop;
위의 식에 대해 컴파일러는 이를 잘못된 작업으로 올바르게 플래그 지정한다.는 GCC를 .error: void value not ignored as it ought to be
및 VC++ 나무껍질'void' illegal with all types
.
내 생각에 당신은 glib가 아닌 glibc를 말하는 것 같은데 문제의 매크로가 바로 the macro이다.assert
매크로:
glibc's eathero.<assert.h>
와 함께NDEBUG
(문서 없음),assert
다음과 같이 정의된다.
#ifdef NDEBUG
#if defined __cplusplus && __GNUC_PREREQ (2,95)
# define __ASSERT_VOID_CAST static_cast<void>
#else
# define __ASSERT_VOID_CAST (void)
#endif
# define assert(expr) (__ASSERT_VOID_CAST (0))
#else
/* more code */
#endif
그 말은 기본적으로assert(whatever);
에 ((void)(0));
그리고 아무것도 하지 않는다.
C89 표준(섹션 4.2):
머리글
<assert.h>
을 규정하다assert
매크로(macro)와 다른 매크로(macro)를 가리킨다.NDEBUG
은 의의 않에 .
<assert.h>
. 만약NDEBUG
소스 파일의 지점에서 매크로 이름으로 정의되며,<assert.h>
되어 있다.assert
매크로는 단순히 로 정의된다.#define assert(ignore) ((void)0)
디버그 인쇄 매크로를 정의하는 것이(void)0
일리가 있다. 수 있니어디서 하는지 보여줄 수 있어?
부작용이 없는 표현은 컴파일러에 의해 거부반응으로 처리될 수 있는데, 컴파일러는 그것에 대해 어떤 코드도 생성하지 않아도 된다.우연히 캐스팅을 한 다음 캐스팅 결과를 사용하지 않는 것은 컴파일러(및 인간)가 부작용을 갖지 않는 것으로 보기 쉽다.
그렇다고 해도, 왜 활자가 그것을 무효로 만들었을까?또한 #define dbgprintf (void) 0의 경우 dbgprintf("Hello World!")와 같이 불릴 때 -> (void) 0("Hello World!"); - 무슨 뜻인가?– 레전드2k
매크로가 코드를 다른 것으로 대체하므로 #defined dbgprint(x를 수락하는 dbgprint)를 다음과 같이 정의하십시오.
무효(0)
그러면 X를 교체할 때 다시 쓸 수 없으므로 dbgprintf("Hellowworld")는 (void) 0("Hello world")로 변환되지 않고 (void) 0으로 변환된다. - 매크로 이름 dbgprint는 (void) 0으로 대체될 뿐만 아니라 전체 통화 dbgprintf("...")
Windows에서 Main.cpp:
#include <iostream>
#define TRACE ((void)0)
int main() {
TRACE("joke");
std::cout << "ok" << std::endl;
return 0;
}
그런 다음 Main.i 출력으로 Release version exe 파일을 빌드한다.Main.i 파일에서 TRACE 매크로는 다음과 같이 대체되었다.((void)0)("joke")
, 그리고 비주얼 스튜디오는 다음과 같이 경고한다:"경고 C4353: 비표준 확장 사용: 함수 표현으로 상수 0.대신 '_noop' 함수의 고유 함수를 사용하십시오."exe 파일을 실행하고 콘솔에서 "확인" 문자를 인쇄하십시오.그래서 나는 모든 것이 명확하다고 생각한다: 매크로 TRACE[#define TRACE ((void)0)]의 정의는 c++ 구문에 따라 불법이지만, 비주얼 스튜디오의 c+++ 컴파일러는 컴파일러 확장자로서 이러한 행위를 지원한다.결론은 [#Define TRACE ((void)0)]는 불법 c++ 문장이며, 기껏해야 이것을 사용하지 마십시오.그러나 [#TRACE(x) ((void)0)]은 법적 진술이다.그게 다야.
참조URL: https://stackoverflow.com/questions/2198950/why-is-void-0-a-no-operation-in-c-and-c
'IT이야기' 카테고리의 다른 글
Vue.js - 웹 팩이 없는 Vuex? (0) | 2022.05.21 |
---|---|
Nuxt 2.14.0에서는 어떤 버전의 Vue를 실행 중인가? (0) | 2022.05.21 |
Vue에서 이벤트 버스 및 Vuex 사용 (0) | 2022.05.21 |
왜 / C의 타입 캐스팅에 'intptr_t'를 사용해야 하는가? (0) | 2022.05.21 |
~asset 폴더의 Vue + Webpack 별칭 동적 이미지 src (0) | 2022.05.21 |