bool에 대한 캐스트 포인터에 성능 경고가 나타나는 이유는 무엇입니까?
확장 .
나는 내가 다음과 같은 일을 할 때 멋지다고 생각했습니다.
bool hasParent () { return this-> parentNode; }
(bool) 캐스트를 사용해도 경고는 여전히 사라지지 않습니다.
여기서 this-> parentNode는 부모 노드가 없을 때 NULL입니다.
그러나 나는 얻는다 :
경고 C4800 : '노드 *': 값을 'true'또는 'false'로 강제 설정 (성능 경고)
무슨 일이야, yo? 이것이 성능 경고 인 이유는 무엇입니까? 나는 다음과 같은 것을 쓰지 않는 것이 더 효율적이라고 생각했습니다.
bool hasParent () { if (this-> parentNode) true를 반환합니다. 그밖에 false 반환; }
그러나 두 번째 버전은 경고를 생성하지 않으며 컴파일러는 훨씬 더 행복해 보입니다. 하지만 어느 것이 더 빠릅니까?
이에 대해 Microsoft Connect에 대한 토론이 있습니다 ( C ++에서 bool로 변환하는 성능에 미치는 영향은 무엇입니까? ). Microsoft에 주어진 예는 다음과 같습니다.
$ cat -n t.cpp && cl -c -W3 -O2 -nologo -Fa t.cpp
1 bool f1 (int i)
2 {
3 return i & 2;
4 }
5
6 bool f2 (int i)
7 {
8 const bool b = i & 2;
9 return b;
10 }
11
12 bool f3 (int i)
13 {
14 const bool b = 0 != (i & 2);
15 return b;
16 }
t.cpp
t.cpp(3) : warning C4800: 'int' : forcing value to bool 'true' or 'false' (performance warning)
t.cpp(8) : warning C4800: 'int' : forcing value to bool 'true' or 'false' (performance warning)
Microsoft의 답변 (경고를 담당하는 개발자의)은 다음과 같습니다.
이 경고는 놀랍게도 도움이되었으며 어제 내 코드에서 버그를 발견했습니다. 나는 Martin이 문맥에서 "성능 경고"를 취하고 있다고 생각합니다.
생성 된 코드가 아니라 프로그래머가 값을 int에서 bool로 변경하려는 의도를 표시했는지 여부입니다. 이에 대한 패널티가 있으며, 사용자는 "boolifying"코드 젠을 피하기 위해 지속적으로 "bool"대신 "int"를 사용할 수 있습니다 (또는 그 반대의 경우). 아래 세 번째 경우에는 int-> bool 전환을 수락하겠다는 의도를 분명히 알 렸기 때문에 경고가 표시되지 않습니다.
오래된 경고이며 목적보다 오래되었을 수 있지만 여기에서 설계된대로 작동합니다.
그래서 기본적으로 MS의 개발자는 '캐스트'원하는 경우라고 말하는 것 같습니다 int
에 bool
더 적절하게 "사용하여 수행해야 return this->parentNode != 0
하는 대신 암시 적 또는 명시 적 캐스트의".
개인적으로 경고에서 어떤 종류의 버그가 발견되는지 더 알고 싶습니다. 이 경고는 그다지 가치가 없을 것이라고 생각합니다.
로 캐스팅 bool
해도 경고가 사라지지 않는 것은 의도적으로 설계된 것입니다 .
식을 bool 형식으로 캐스팅해도 경고가 비활성화되지는 않습니다. 이는 의도적으로 설계된 것입니다.
C4800 경고에 대한 MSDN 설명에서 권장하는 접근 방식을 권장합니다.
return this->parentNode != NULL;
이것은 당신이 반환하는 것이 분명하게 true
하면 parentNode
널 포인터가 아니고, false
경우는 parentNode
널 포인터이다.
컴파일러는 포인터를 bool로 변환하기위한 추가 코드를 생성해야합니다. 기본적으로 0에 대한 비교이며 0이 아닌 경우 결과를 1로 설정합니다.
00000000004005e0 <_Z4testPv>:
bool test(void* adr) {
4005e0: 48 85 ff test %rdi,%rdi
4005e3: 0f 95 c0 setne %al
return adr;
}
4005f8: c3 retq
이것은 소스에서 직접 볼 수 없기 때문에 컴파일러는 이것이 사용자에게 경고해야 할 것이라고 생각합니다.
이것이 성능 경고 인 이유는 무엇입니까?
컴파일러는 이것을 바꾸고 있습니다.
bool hasParent()
{
return this->parentNode;
}
으로:
bool hasParent()
{
return this->parentNode != 0;
}
이것은 코드를 볼 때 예상 할 수있는 것보다 약 한 클럭주기가 더 걸립니다 . 성능 차이는 미미합니다.
!= 0
어쨌든 명시 적으로 작성하는 것이 더 낫다고 생각합니다 . 코드를 더 명확하게 만들고 경고를 없애기 때문입니다.
다음과 같이 작성하는 것이 더 효율적입니다.
bool hasParent()
{
return this->parentNode != NULL;
}
나는 이것이 컴파일러에 의존적이라고 확신합니다.
현실적으로 나는 그들이 똑같이 최적화 할 것이라고 생각하며, 이것을 시도 할 수도 있습니다.
return this->parentNode != 0;
'IT이야기' 카테고리의 다른 글
Javascript / Ajax의 HTTP HEAD 요청 (0) | 2021.04.23 |
---|---|
ASP.NET 웹 페이지 요청에 의해 트리거 된 비동기 작업 실행 (0) | 2021.04.23 |
나만의 자바 라이브러리 (API)를 만드는 방법 (0) | 2021.04.22 |
Hg에서 한 지점으로만 푸시하는 방법 (0) | 2021.04.22 |
매번 열리는 성능 탐색기 비활성화 (0) | 2021.04.22 |