C ++ 11에서 가능성이 있거나 가능성이없는 매크로를 정의하는 올바른 방법은 다음과 같습니다.
#define LIKELY(condition) __builtin_expect(static_cast<bool>(condition), 1)
#define UNLIKELY(condition) __builtin_expect(static_cast<bool>(condition), 0)
이 메서드는와 달리 모든 C ++ 버전과 호환 [[likely]]
되지만 비표준 확장에 의존합니다 __builtin_expect
.
이러한 매크로가 이렇게 정의 된 경우 :
#define LIKELY(condition) __builtin_expect(!!(condition), 1)
이것은 if
문장 의 의미를 바꾸고 코드를 깨뜨릴 수 있습니다. 다음 코드를 고려하십시오.
#include <iostream>
struct A
{
explicit operator bool() const { return true; }
operator int() const { return 0; }
};
#define LIKELY(condition) __builtin_expect((condition), 1)
int main() {
A a;
if(a)
std::cout << "if(a) is true\n";
if(LIKELY(a))
std::cout << "if(LIKELY(a)) is true\n";
else
std::cout << "if(LIKELY(a)) is false\n";
}
그리고 출력 :
if(a) is true
if(LIKELY(a)) is false
보시다시피 LIKELY를 !!
캐스트로 사용하는 정의 bool
는 if
.
여기서 요점은하지 operator int()
와 operator bool()
관련되어야한다. 좋은 습관입니다.
오히려 그 사용하는 !!(x)
대신 static_cast<bool>(x)
에 대한 컨텍스트 손실 C ++ (11) 문맥 변환을 .