2013-08-29 3 views
8

<windows.h> शीर्षलेख अपने BOOL प्रकार के साथ आता है। कार्यान्वयन पर ध्यान देते हुए, ऐसा लगता है कि FALSE0 के लिए सिर्फ एक मैक्रो है, और TRUE1 के लिए सिर्फ एक मैक्रो है, लेकिन मुझे यकीन नहीं है कि यह निर्दिष्ट है।मैं मूर्खतापूर्वक एक बूल को एक बूल में कैसे परिवर्तित करूं?

BOOL को bool में परिवर्तित करने के लिए बेवकूफ तरीका क्या है?

bool a = static_cast<bool>(x); 

bool b = x ? true : false; 

bool c = (x == TRUE); 

bool d = (x != FALSE); 

bool e = !!x; 

// ... 
+0

"idiomatic" से आपका क्या मतलब है? –

+0

'बूल सी = (एक्स == गलत)'? :) – Inspired

+0

यह एसओ के लिए शायद अनुचित है क्योंकि यह व्यक्तिगत स्वाद के लिए उबाल जाता है, मुझे विश्वास है। – lpapp

उत्तर

6

किसी भी स्पष्ट रूपांतरण के लिए कोई ज़रूरत नहीं है:: मैं संभव तरीके के बहुत सारे कल्पना कर सकते हैं

BOOL x = some_value; 
bool b = x; 

bool पर संख्यात्मक प्रकार के निहित रूपांतरण 0 के एक मूल्य के लिए false पैदावार, और true के लिए कोई गैर-शून्य मान।

संयोग से, आपने हमें बताया है कि <windows.h>FALSE और TRUE को परिभाषित करता है। यह BOOL को कैसे परिभाषित करता है? (आपकी टिप्पणी से, यह typedef int BOOL;)

लेकिन कुछ कंपाइलर इस अंतर्निहित रूपांतरण के बारे में चेतावनी दे सकते हैं, भले ही यह पूरी तरह से वैध कोड है। कंपाइलर्स आपके पसंदीदा कोड के बारे में चेतावनी देने के लिए स्वतंत्र हैं, जिसमें आपके कोड को लिखने के लिए उपयोग किए गए बदसूरत फ़ॉन्ट भी शामिल हैं। जी ++, उदाहरण के लिए, परिवर्तन के बारे में, यहां तक ​​कि साथ में शिकायत नहीं करता है:

g++ -std=c++11 -pedantic -Wall -Wextra ... 

लेकिन this online Visual C++ compiler के अनुसार, कुलपति ++ एक चेतावनी का उत्पादन करता है:

warning C4800: 'BOOL' : forcing value to bool 'true' or 'false' (performance warning) 
यहां तक ​​कि एक static_cast साथ

, यह अभी भी पैदा करता है चेतावनी।

आप !!x या x ? true : false का उपयोग कर चेतावनी से बच सकते हैं। लेकिन मुझे यकीन नहीं है कि बीमारी से इलाज बेहतर है।

ऐसा करने का सरल और सही तरीका केवल मूल्य असाइन करना है और सही चीज़ करने के लिए अंतर्निहित रूपांतरण पर भरोसा करना है (यह होगा)।

यदि आपके पास कंपाइलर चेतावनियों से बचने के लिए अतिरिक्त आवश्यकता है, तो यह C++ भाषा के बजाय दृश्य C++ के बारे में अधिक प्रश्न बन जाता है। स्रोत को बदलने के बिना कुछ चेतावनियों को बाधित करने का कोई तरीका भी हो सकता है - हालांकि वे वास्तव में समझ में आने पर उन चेतावनियों को खोने का जोखिम उठाते हैं। एक टिप्पणी में, डाइटर लुकिंग ने सुझाव दिया:

#pragma warning(disable: 4800) // forcing value to bool 'true' or 'false' (performance warning) 

लेकिन ऐसा लगता है कि इसे अभी भी स्रोत को संशोधित करने की आवश्यकता है। शायद कुछ समकक्ष है जो नहीं करता है।

एक और बात: BOOL के बाद से वास्तव में टाइप है int, इस प्रस्तावित समाधान:

bool c = (x == TRUE); 

दूसरों के बराबर नहीं है। कोई भी गैर-शून्य int को सत्य माना जाता है, लेकिन केवल 1 मान बराबर से TRUE पर है।उपर्युक्त cfalse पर x == 2 सेट करेगा, उदाहरण के लिए - जबकि if (x) अभी भी इसे एक वास्तविक स्थिति के रूप में पेश करेगा। समानता के लिए बूलियन मानों की तुलना कभी भी true या TRUE से करें। (उन्हें false या FALSE सुरक्षित, लेकिन अभी भी अनावश्यक है की तुलना करना;। कि क्या ! ऑपरेटर के लिए है)

यह सब मान लिया गया है, तो आप प्रकार BOOL के एक मूल्य है, तो आप केवल परवाह है कि क्या यह falsish या truthy है (शून्य या शून्य नहीं)। दुर्भाग्यवश, यह हमेशा मामला नहीं हो सकता है। Ben Voight's answer बताते हैं, माइक्रोसॉफ्ट के एपीआई में कम से कम एक समारोह, GetMessage शामिल है, जो BOOL परिणाम देता है जो एक साधारण बूलियन मान नहीं है। इस तरह के एक भयानक मामले में, BOOL से bool में रूपांतरण उचित नहीं है यदि आपको एकाधिक गैर-शून्य मानों में अंतर करने की आवश्यकता है।

आखिरकार, मैं एक ऐसी भाषा के लिए BOOL को परिभाषित करने के लिए माइक्रोसॉफ्ट को दोष देता हूं, जिसमें पहले से ही पूरी तरह से अच्छी तरह से व्यवहार किया गया है bool प्रकार। असल में यह काफी उचित नहीं है; इसका उपयोग उन एपीआई में किया जाता है जिन्हें सी और सी ++ दोनों से सुलभ होने की आवश्यकता होती है। BOOL की माइक्रोसॉफ्ट की परिभाषा शायद उनके सी कार्यान्वयन पर वापस आती है, जहां यह कुछ समझ में आता है - कम से कम सी 99 से पहले, जो माइक्रोसॉफ्ट अभी भी समर्थन नहीं करता है। (। मैं कि क्या माइक्रोसॉफ्ट के सी संकलक समर्थन _Bool यहां तक ​​कि अगर यह होता है, _Boolint से कुछ अर्थ मतभेद है पता नहीं है, और BOOL की परिभाषा बदल रहा है कुछ कोड तोड़ सकता -। विशेष रूप से कोड GetMessage का उपयोग करता है)

+2

यह मुझे एक कंपाइलर चेतावनी देता है। अन्यथा मैंने नहीं पूछा होगा :) – fredoverflow

+0

'typedef int BOOL; ' – fredoverflow

+1

@FredOverflow: चेतावनी क्या है? (और आपने इसका जिक्र क्यों नहीं किया, और अपने मूल प्रश्न में चेतावनी उद्धृत की?) कंपाइलर्स अपनी पसंद के बारे में चेतावनी दे सकते हैं; जीसीसी, उदाहरण के लिए, * * '' 'से' bool' तक एक अंतर्निहित रूपांतरण के बारे में चेतावनी नहीं देता है। और टाइपिफ़ को दिखाने के लिए कृपया अपना प्रश्न अपडेट करें। –

0

यह

bool c = (X == TRUE); 

या

bool d = (x != FALSE); 

मुझे लगता है कि यह एक बुरा पी है: कहने के लिए कैसे Win32 प्रोग्रामर यह करना होगा, लेकिन यह IMHO द्वारा किया जाना चाहिए कठिन मैक्रो (या किसी अन्य पूर्वनिर्धारित सामान) पर रिले करने के लिए रैक्टिस
स्थिरता।

एक दिन सही 0 और असत्य 1 हो सकता है;)

+1

वह दिन अब है, ['VARIANT_BOOL'] (http://msdn.microsoft.com/en-us/library/cc237864.aspx) को बाद में परिभाषित किए जाने के साथ 'VARIANT_FALSE' और' VARIANT_TRUE' असाइन किया जा सकता है '(लघु) -1' के रूप में, दूसरे शब्दों में 0xFFFF। विंडोज़ पर मैं हमेशा 'बूल डी = (एक्स! = गलत) का उपयोग करने का सुझाव दूंगा; '। आप अपनी टीम के सभी को यह जानने की उम्मीद नहीं कर सकते कि 'VARIANT_BOOL' से' BOOL' में कैसे परिवर्तित किया जाए। – IInspectable

0

क्योंकि Win32 BOOLmore than two values है वहाँ, यह करने के लिए कोई सुरक्षित तरीका है।

#define _bool(b) (!!(b)) 

IMO, मेरे कोड अधिक पठनीय बनाता है:

+0

ऐसा माना जाता है कि आपको उन मानों को बनाए रखने की आवश्यकता है। यदि इसका उपयोग सैनिली रूप से किया जा रहा है, तो आपको केवल यह ध्यान रखना चाहिए कि यह सच है या गलत है। –

+0

@ किथ: यह कई एपीआई के लिए सच है, लेकिन जिसे मैंने लिंक किया है वह तीन समकक्ष वर्गों से मूल्य लौटाता है। –

+0

यह एक बेवकूफ, बेवकूफ, बेवकूफ एपीआई है। (रिटर्न प्रकार को 'BOOL' से' int 'में बदलना उस समस्या को हल करेगा और एपीआई में कोई फर्क नहीं पड़ता।) –

1

मैं मैक्रो का उपयोग।

संपादित: एक टिप्पणीकर्ता ने मैक्रो नाम में अंडरस्कोर के उपयोग को चुनौती दी है। इसे हल करने के लिए, यहां एक नया संस्करण है जो अभी भी सामान्य है और अभी भी _bool का नाम उसी नाम का उपयोग करता है, लेकिन this के अनुसार, अनुपालन करता है।

namespace MyBool 
{ 
    template<typename T> inline bool _bool(const T b) 
    { 
     return !!b; 
    } 
} 

using namespace MyBool; 
+0

वैश्विक नामस्थान में अंडरस्कोर से शुरू होने वाले नाम [आरक्षित] हैं [http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-ac-identifier) । – IInspectable

+0

मेरे लिए कोई समस्या नहीं है। यह मैक्रो केवल अपने कोड द्वारा उपयोग किया जाता है और प्री-प्रोसेसर द्वारा विस्तारित किया जाता है, इसलिए कंपाइलर और नेमस्पेस इसके बारे में कुछ नहीं जानते हैं। वैसे भी, कोई '__bool' का उपयोग कर सकता है। – avo

+0

एक नाम जिसमें डबल अंडरस्कोर है, आरक्षित ** हर जगह ** है। इसका ** आपके ** कोड के साथ कुछ लेना देना नहीं है। C++ कार्यान्वयन के साथ नाम संघर्ष को रोकने के लिए नियम हैं। आप निश्चित रूप से एक मानक लाइब्रेरी हेडर नहीं चाहते हैं कि इसका उपयोग कर कोड के साथ संघर्ष के लिए गार्ड शामिल हों। एक सुरक्षित विकल्प होगा: 'बूल बूल_ (कॉन्स बूल बी) {रिटर्न !! बी;} ' – IInspectable

0

यह कुछ हद तक एक राय प्रश्न है, लेकिन मुझे लगता है कि विभिन्न विकल्पों के लिए उद्देश्य तर्क दिए जाने हैं।

सबसे अच्छा विकल्प है:

bool d = (x != FALSE); 

इस आशय पाठक के लिए बहुत स्पष्ट करता है, अंतर्निहित रूपांतरण पर निर्भर नहीं करता, और यह स्पष्ट भी है एक सरल काम से चल रहा है कि बनाता है।

दूसरा सबसे अच्छा विकल्प है:

bool b = x ? true : false; 

लेकिन, आकस्मिक पाठक को, कि एक अनुलाप की तरह लग सकता है।

मैं असाइनमेंट में निहित रूपांतरणों से बचने की कोशिश करता हूं क्योंकि गलत रूपांतरण प्राप्त करना बग का एक आश्चर्यजनक स्रोत है। यहां तक ​​कि जब मैं जानता हूं निहित रूपांतरण सही काम करेगा, मैं इसे स्पष्ट रूप से करता हूं, जो भविष्य में कोड पढ़ने वाले किसी के लिए उपयोगी हो सकता है। स्पष्ट होने से आप रूपांतरण चेतावनियां सक्षम भी कर सकते हैं ताकि आप अन्य अंतर्निहित रूपांतरणों को पकड़ सकें जिन्हें आप नहीं जानते थे कि आप (एबी) का उपयोग कर रहे थे।

विकल्पों में सभी को गंभीर गंभीरताएं हैं।

bool a = static_cast<bool>(x); 

यह एक गोल छेद में एक वर्ग चरम को हथौड़ा जैसा है। यह एक अभिव्यक्ति लिखने के लिए और अधिक सुरुचिपूर्ण है जो स्वाभाविक रूप से सही प्रकार देता है।

bool c = (x == TRUE); 

यह आम तौर पर एक बुरा विचार TRUE से तुलना करने के लिए, के बाद से अन्य ग़ैर शून्य मान झूठी है, जो लगभग निश्चित रूप से एक त्रुटि है करने के लिए बदल जाएगा।

bool e = !!x; 

आपके विकल्पों का सटीक रूप से व्यक्त करने वाले विकल्पों की तुलना में बहुत चालाक। (मैंने पहले भी यह किया करने का दोषी हूँ।)

bool f = x; 

प्रदर्शन चेतावनी MSVC++ विशुद्ध रूप से निहित रूपांतरण पर उत्सर्जन करता है उचित लगता है। कंपाइलर को एक int को एक बूल में बदलने के लिए अतिरिक्त कोड उत्पन्न करना होता है। बेयर असाइनमेंट इस अतिरिक्त काम के बारे में थोड़ा संकेत देता है। यदि यह एक तंग पाश में है, तो आप परवाह कर सकते हैं। (दी, static_cast विकल्प पर प्रदर्शन चेतावनी प्रबल लगता है, लेकिन हम पहले से ही उस की संभावना से इनकार किया है कम सुरुचिपूर्ण के रूप में।)

d और b भाव स्पष्ट रूप से आशय व्यक्त करने और यह स्पष्ट से अधिक यहां हो रहा है कि बनाने के एक प्रत्यक्ष असाइनमेंट।

संबंधित मुद्दे