IT이야기

bool에 대한 캐스트 포인터에 성능 경고가 나타나는 이유

cyworld 2021. 4. 22. 21:15
반응형

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의 개발자는 '캐스트'원하는 경우라고 말하는 것 같습니다 intbool더 적절하게 "사용하여 수행해야 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;

참조 URL : https://stackoverflow.com/questions/1847860/why-is-there-a-performance-warning-on-cast-pointer-to-bool

반응형