왜 사용! int를 bool로 변환 할 때?
이런 식으로 정수를 부울로 변환하는 이유는 무엇입니까?
bool booleanValue = !!integerValue;
그냥 대신
bool booleanValue = integerValue;
내가 아는 것은 VC ++ 7에서 후자는 C4800 경고 를 유발 하고 전자는 그렇지 않다는 것입니다. 둘 사이에 다른 차이점이 있습니까?
"!!"의 문제점 관용구는 간결하고,보기 어렵고, 오타로 착각하기 쉽고, "! 's"중 하나를 삭제하기 쉬운 등입니다. "C / C ++로 얼마나 귀여울 수 있는지"카테고리에 넣었습니다.
그냥 쓰십시오 bool isNonZero = (integerValue != 0);... 명확하게.
역사적으로, !!관용구는 부울 정말 기대 두 값 중 하나에 포함되도록하는 데 사용 된 boolC 및 C ++ 진정한 없었기 때문에, -like 변수 bool유형을 우리는 그것을 위조 int들. 이것은 이제 "실제"에서 문제가되지 않습니다 bool.
그러나 사용은 !!예, 당신은 정말 캐스트에 의도 않았다 (코드에서 작업 컴파일러와 미래의 두 사람을위한) 문서화하는 효율적인 수단이다 intA를 bool.
C 언어 (및 일부 사전 표준 C ++ 컴파일러도)에 bool유형 이 없었기 때문에 사용 int됩니다. 따라서 ints는 논리 값을 나타내는 데 사용 되었습니다 . 0의미 false는이고 나머지는 모두입니다 true. !운영자는 반환되었다 1에서 0와 0다른 모든 것들로부터. Double !은 그것들을 반전시키는 데 사용되었으며 값이 논리 값에 따라 0또는 1그 값에 의존 하는지 확인하기 위해 사용되었습니다 .
C ++에서는 적절한 bool유형을 도입했기 때문에 더 이상 그렇게 할 필요가 없습니다. 그러나 모든 레거시 소스를 단순히 업데이트 할 수는 없으며 C와 C ++ (대부분의 경우)의 하위 호환성으로 인해 업데이트 할 필요도 없습니다. 그러나 많은 사람들이 여전히 bools를 이해하지 못하는 오래된 컴파일러와 이전 버전과 호환되는 코드를 유지하기 위해 동일한 이유에서 여전히 그렇게합니다 .
그리고 이것이 유일한 진정한 답입니다. 다른 답변은 오해의 소지가 있습니다.
! integerValue는 integerValue == 0을 의미하고 !! integerValue는 integerValue! = 0을 의미하므로 bool을 반환하는 유효한 표현식입니다. 후자는 정보 손실이있는 캐스트입니다.
또 다른 옵션은 어셈블리 코드를 한 줄 적게 생성하는 삼항 연산자입니다 (어쨌든 Visual Studio 2005에서는).
bool ternary_test = ( int_val == 0 ) ? false : true;
어셈블리 코드를 생성합니다.
cmp DWORD PTR _int_val$[ebp], 0
setne al
mov BYTE PTR _ternary_test$[ebp], al
대:
bool not_equal_test = ( int_val != 0 );
다음을 생성합니다.
xor eax, eax
cmp DWORD PTR _int_val$[ebp], 0
setne al
mov BYTE PTR _not_equal_test$[ebp], al
큰 차이가 아니라는 것을 알고 있지만 궁금해서 결과를 공유하겠다고 생각했습니다.
부울은 0과 1의 두 가지 상태 만 가질 수 있습니다. 정수는 부호있는 32 비트 정수를 가정 할 때 -2147483648에서 2147483647 사이의 모든 상태를 가질 수 있습니다. 단항! 연산자는 입력이 0이면 1을 출력하고 입력이 0이 아니면 0을 출력합니다. 따라서! 0 = 1이고! 234 = 0입니다. 두 번째! 단순히 출력을 전환하여 0이 1이되고 1이 0이됩니다.
따라서 첫 번째 명령문은 booleanValue가 0 또는 1과 동일하게 설정되고 다른 값이 없음을 보장하지만 두 번째 명령문은 그렇지 않습니다.
!!은 (는)로 변환하는 관용적 방법 bool이며 이러한 변환의 비 효율성에 대한 Visual C ++ 컴파일러의 어리석은 경고를 차단합니다.
다른 답변과 의견을 보면 많은 사람들이 Windows 프로그래밍에서이 관용구의 유용성에 익숙하지 않다는 것을 알 수 있습니다. 이는 그들이 심각한 Windows 프로그래밍을하지 않았 음을 의미합니다. 그리고 그들이 만난 것이 대표적이라고 맹목적으로 가정하십시오 (그렇지 않습니다).
#include <iostream>
using namespace std;
int main( int argc, char* argv[] )
{
bool const b = static_cast< bool >( argc );
(void) argv;
(void) b;
}
> [d : \ dev \ test] > cl foo.cpp foo.cpp foo.cpp (6) : 경고 C4800 : 'int': 값을 'true'또는 'false'로 강제 설정 (성능 경고) [d : \ dev \ test] > _
And at least one person thinks that if an utter novice does not recognize its meaning, then it's ungood. Well that's stupid. There's a lot that utter novices don't recognize or understand. Writing one's code so that it will be understood by any utter novice is not something for professionals. Not even for students. Starting on the path of excluding operators and operator combinations that utter novices don't recognize... Well I don't have the words to give that approach an appropriate description, sorry.
Cheers & hth.,
The answer of user143506 is correct but for a possible performance issue I compared the possibilies in asm:
return x;, return x != 0;, return !!x; and even return boolean_cast<bool>(x) results in this perfect set of asm instructions:
test edi/ecx, edi/ecx
setne al
ret
This was tested for GCC 7.1 and MSVC 19 2017. (Only the boolean_converter in MSVC 19 2017 results in a bigger amount of asm-code but this is caused by templatization and structures and can be neglected by a performance point of view, because the same lines as noted above may just duplicated for different functions with the same runtime.)
This means: There is no performance difference.
PS: This boolean_cast was used:
#define BOOL int
// primary template
template< class TargetT, class SourceT >
struct boolean_converter;
// full specialization
template< >
struct boolean_converter<bool, BOOL>
{
static bool convert(BOOL b)
{
return b ? true : false;
}
};
// Type your code here, or load an example.
template< class TargetT, class SourceT >
TargetT boolean_cast(SourceT b)
{
typedef boolean_converter<TargetT, SourceT> converter_t;
return converter_t::convert(b);
}
bool is_non_zero(int x) {
return boolean_cast< bool >(x);
}
No big reason except being paranoid or yelling through code that its a bool.
for compiler in the end it wont make difference .
I've never like this technique of converting to a bool data type - it smells wrong!
Instead, we're using a handy template called boolean_cast found here. It's a flexible solution that's more explicit in what it's doing and can used as follows:
bool IsWindow = boolean_cast< bool >(::IsWindow(hWnd));
참고URL : https://stackoverflow.com/questions/1310344/why-use-when-converting-int-to-bool
'Program Club' 카테고리의 다른 글
| Swift 4의 Decodable 프로토콜에서 사용자 지정 키를 어떻게 사용합니까? (0) | 2020.10.15 |
|---|---|
| 목록의 모든 요소 쌍에 대한 작업 (0) | 2020.10.15 |
| jquery 클릭이 ajax 생성 콘텐츠에서 작동하지 않습니다. (0) | 2020.10.15 |
| PHP-FPM 및 Nginx : 502 불량 게이트웨이 (0) | 2020.10.15 |
| "strlen (s1)-strlen (s2)"는 0보다 작지 않습니다. (0) | 2020.10.15 |