2008-10-15 3 views
49

[이 질문은 관련이 있지만 this one과 동일하지 않습니다.]입니다 !! C에서 bool로 변환하는 안전한 방법 + +?

내가 부울 식으로 특정 유형의 값을 사용하려고하면, 내가 경고를 얻을. 경고를 억제하기보다는 때때로 삼항 연산자 (?:)를 사용하여 bool로 변환합니다. 연산자가 아닌 두 개 (!!)를 사용하면 같은 효과가있는 것 같습니다. 더 - 더블없는 기술은 정말 같은 일을

typedef long T;  // similar warning with void * or double 
T t = 0; 
bool b = t;   // performance warning: forcing 'long' value to 'bool' 
b = t ? true : false; // ok 
b = !!t;    // any different? 

그래서 않습니다 여기

은 무슨 뜻입니까? 그것은 삼중 기법보다 더 안전합니까? 이 기술은 비 필수 유형 (예 : void * 또는 doubleT)으로 동일하게 안전합니까?

!!t이 좋은 스타일인지 묻지 않습니다. 의미 적으로 t ? true : false과 다른지 묻습니다.

+3

내가 좋아하는 줄 참조 "B = t 진실은? 거짓;" 나는 항상 그것을 "b = t"라는 줄로 바꾸려고한다. bool에 대한 암시 적 캐스트가 이미 있습니다. 왜 의미가 의미가 있습니까? –

+2

Q가 말하기를, b = t는 주저에 따라 얼마나 많은 사람들이'!!'에 반대하는지에 대한 경고를주기 때문에 – jwfearn

+2

입니다. double negation은 * 자바 스크립트에서 * 숙어가되는 캐스팅 - 투 - 부울 (bubi-to-bool) 차량이며, javascripters가 그것을 얻는다면 C++ 사용자도 기대할 것입니다. –

답변

83

! 연산자와 삼항 연산자의 첫 번째 인수는 모두 암시 적으로 bool로 변환되므로 !! 및? :는 캐스트의 IMO 바보 같은 중복 장식입니다. 투표 대상 :

b = (t != 0); 

암시 적 변환 없음.

+4

또한 읽을 수 있습니다. –

6

모든 유효한 기술은 모두 동일한 코드를 생성합니다.

개인적으로 가장 간단한 구문을 사용할 수 있도록 개인적으로 경고를 비활성화합니다. bool에 캐스팅하는 것은 우연히하는 것에 대해 걱정하고있는 것이 아닙니다.

+4

그래, 분명하고 관용적 인 C 코드에 대한 경고를 Microsoft에 보내 주셔서 감사합니다. –

+0

경고를 추가하게 한 것이 무엇인지 궁금합니다. 누군가 정말로 무언가를하고 있었어야했는데 ... –

+0

아마 특정 타겟 아키텍처에 어떤 의미가 있을까요? MS는 그래서 컴파일러는 당신이하려는되지 않을 수 있습니다 뭔가에 대해 당신이 "WARN"수 정상적인 캐스트와 전환 경고 @MikeF – jwfearn

41

또는이 작업을 수행 할 수 있습니다 : 당신이 경고에 대한 걱정이 있다면 bool b = (t != 0)

+4

나는 이것이 가장 명확하게 의도를 표현한다고 생각하기 때문에 항상이 것을 사용합니다. 이는 컴파일러가 경고를 생성하는 경우 효과적으로 수행하지만 명시 적입니다. 그 !! 나에게 해커처럼 보인다. – rmeador

+0

t가 연산자 (bool)를 제공하는 객체 인 경우 작동하지 않지만 다른 제안은 수행합니다. – Jules

2

은 또한 캐스트를 강제 할 수 bool b = (bool)t;

+1

실제로 이는 bool b = t와 정확히 동일합니다. – jwfearn

+0

C 캐스트를 사용하지 마십시오. C++ 캐스트는 이유가 있습니다. 또한 컴파일러에서이 작업을 시도하지는 않았지만 컴파일러에게 무언가를하도록 명시 적으로 요청했기 때문에 경고를 생성 할 것이라고 기대하지는 않습니다. 컴파일러는 암시적인 일이 발생할 때만 경고합니다. – wilhelmtell

+0

이런 식으로 할 때 우분투 상자의 GCC 아래에 경고가 표시되지 않습니다. – warren

6


예는 안전합니다.


0 따라서 , 다른 모든게은 사실, 거짓으로
를 해석됩니다! (5) 거짓
로 나온다! 0
이렇게! 5

1

참으로 나오는 참으로 나온다! 소형일지도 모르지만, 불필요하게 복잡하다고 생각합니다. 제 의견으로는 경고를 사용하지 않거나 삼항 연산자를 사용하는 것이 좋습니다.

-1

두 배로 나에게 재미 있고 디버그 코드는 최적화 된 코드와 매우 다를 것입니다.

당신이 맘에 든다면 !! 당신은 항상 매크로를 할 수 있습니다.

#define LONGTOBOOL(x) (!!(x)) 

나는 결코 그 경고를 억제하지 않으며, 결코 그것을 억제하기 위해 C 캐스트 (BOOL)를 사용하지 않는 것이 좋습니다

3

(AN 등은 제외하고, 삼항 연산자는 내가 이러한 경우에 선호하는 것입니다). 생각한대로 전환이 항상 호출되는 것은 아닙니다.

true로 평가되는 표현식과 해당 값의 부울 값간에 차이가 있습니다.

모두 !! 그리고 ternary는 익숙해 지지만 bool에 오버로드 된 형을 가진 내부 형을 정의하고 싶지 않다면 비슷한 일을 할 것이다.

Dima의 접근 방식은 표현식의 값을 bool에 지정하므로 너무 좋습니다.

+0

경고가 어떤 식 으로든 도움이 될 수있는 예를 생각해 보시나요? –

+0

글쎄, 캐스트에서 정보가 손실되었을 수 있습니다. 어쩌면이 변환에서 정보가 손실되지 않는 환경에서 코드를 포팅하는 것일 수 있습니다. 이 경우 잃어버린 부분에 대해 알고 싶습니까? – wilhelmtell

+0

물론 정보를 잃어 버리고 있습니다. 그것은 bool로 변환의 전체 지점입니다! –

0

필자는 b = (0! = t)를 사용합니다. 적어도 정상적인 사람이라면 쉽게 읽을 수 있습니다. 코드에 이중 덩어리가 보일 경우, 나는 꽤 놀랄 것입니다.

5

내가 사용하지 것이다 :

다른 사람은 상황에 따라 (유지하기 때문에 어려운 등)을 적어도 읽을 수있는 방법

입니다

bool b = !!t; 

.
bool 표현식에서만 사용하도록 변환하는 경우.

bool b = t ? true : false; 
if (b) 
{ 
    doSomething(); 
} 

은 그 때 나는 언어가 당신을 위해 그것을 할 것입니다 :

if (t) 
{ 
    doSomething(); 
} 

실제로 부울 값을 저장하는 경우. 그렇다면 먼저 캐스팅이 필요한 첫 번째 장소에서 왜 오래 있는지 궁금해 할 것입니다. 당신이 long과 bool 값을 필요로한다고 가정 할 때 나는 상황에 따라 다음을 모두 고려할 것입니다.

bool b = t ? true : false;  // Short and too the point. 
           // But not everybody groks this especially beginners. 
bool b = (t != 0);    // Gives the exact meaning of what you want to do. 
bool b = static_cast<bool>(t); // Implies that t has no semantic meaning 
           // except as a bool in this context. 

요약 :. 당신이있는 상황에 가장 의미를 제공하는 것 사용
시도하고

+0

"let the language does it"(일명 '평범한 변환')은 경고를 생성합니다. 이것이 필요할 때의 예 : struct C {void * hdl; void * get_hdl() {return hdl; } bool has_hdl() const {return hdl? 허위 사실; } – jwfearn

+7

가독성은 보는 사람의 눈에 있습니다. 예를 들어, 접두어 연산자는 후위 연산자보다 더 읽기 쉽고, 자세한 정보는 간결하고, 중복 이상의 건조는 고려합니다. (double) 부정은 접두어 연산자 (win)이며, 3 진 (win)보다 짧으며 단일 연산자로 인식 될 수 있지만 3 항은 3 개의 고유 한 표현식 (연산자 구문 사용)을 전달합니다. –

-4

내가 부울 B = t을 사용하고있는 것이 분명 무엇을하고 컴파일을 떠나 이 라인의 안전에 대해 언급하면서 경고했다. 경고를 비활성화하면 코드의 다른 부분에서 엉덩이에 물린 수 있습니다.

+5

무시해야 할 경고를 남기는 것은 생산성이 떨어집니다. 다른 중요한 경고를 놓칠 수 있습니다. 제로 경고 정책이 가장 좋습니다. –

+0

예,하지만 경고를 더 이상 사용하지 않으면 경고가 더 중요 할 수 있습니다. 에드거가 말했듯이, 부랑자는 진리 - 가치에 관한 것이고, 정수는 숫자에 관한 것입니다. 그 구별은 어떻게 든 보존되어야합니다. –

-1

나는

경우 사용하는 것이 좋습니다

또는

경우 (X = NULL을!)

아닌 경우의 (X) (X를! = 0); 더 이해할 수 있고 읽을 수 있습니다.

+2

제게'if (x)'가 더 읽기 쉽습니다. 가장 간결한 방식으로 '0이 아니라면'이라고 말합니다. –

31

조심하세요!

  • 부울은 진실과 거짓에 관한 것입니다.
  • 정수는 정수입니다.

그은 매우 독특한 개념입니다 :

  • 진위는 물건을 결정에 관한 것입니다.
  • 숫자는 계산에 관한 것입니다.

이러한 개념을 연결하는 경우 명시 적으로 수행해야합니다.나는 최고의 디마의 버전을 좋아한다 :

b = (t != 0);

그 코드는 분명하게 말한다 : 두 숫자를 비교하고 부울의 진리 값을 저장합니다.

2

는 정말 !! t 싫어 !!!!!!. 그것은 C와 C++에 관한 최악의 상황을 헤쳐 나옵니다. 신택스가 너무 작아서 유혹에 빠지기 쉽습니다.

부울 B (t! = 0); // IMHO가 가장 좋은 방법인가, 명시 적으로 어떤 일이 일어나는지 보여줍니다.

0

경고를 사용하지 않도록 설정합니다. 첫째 선명도

쓰기; 다음 프로필; 필요한 경우 속도를 최적화하십시오.

0

!! 당신이 :, 예컨대을 산술 방식으로 부울 식을 사용하는 경우에만 유용합니다

c = 3 + !!extra; //3 or 4 

(누구의 스타일을 다른 토론입니다.) 당신이 필요로하는 모든이의 부울 식입니다 때! 중복이다.

bool b = !!extra; 

를 작성하는 것은 많은 의미가로 :

if (!!extra) { ... } 
관련 문제