2011-12-19 10 views
5

का उपयोग करते समय मैं चेतावनी स्तर/W4 सक्षम के साथ विजुअल स्टूडियो 2010 सी ++ कंपाइलर (X86) का उपयोग कर निम्न C++ प्रोग्राम को संकलित करने का प्रयास करता हूं, मुझे एक हस्ताक्षरित/हस्ताक्षरित मेलसमैच चेतावनी मिलती है चिह्नित रेखा।सी ++: साइन किए गए/हस्ताक्षरित मेल नहीं खाते जब केवल हस्ताक्षर किए गए प्रकार

#include <cstdio> 
#include <cstdint> 
#include <cstddef> 

int main(int argc, char **argv) 
{ 
    size_t idx = 42; 
    uint8_t bytesCount = 20; 

    // warning C4389: '==' : signed/unsigned mismatch 
    if (bytesCount + 1 == idx) 
    { 
     printf("Hello World\n"); 
    } 

    // no warning 
    if (bytesCount == idx) 
    { 
     printf("Hello World\n"); 
    } 
} 

यह मुझे भ्रमित करता है, क्योंकि मैं केवल हस्ताक्षरित प्रकारों का उपयोग कर रहा हूं। तुलना

bytesCount == idx 

ऐसी कोई चेतावनी का कारण बनता है के बाद से, यह शायद कुछ अजीब अंतर्निहित बातचीत कि यहां होता से कोई लेना देना नहीं है।

इस प्रकार: मुझे यह चेतावनी क्यों मिलती है और यह वार्तालाप किस नियम से होता है (यदि यह कारण है)?

उत्तर

5

1 एक int है। एक अभिन्न अंकगणितीय अभिव्यक्ति का प्रकार शामिल प्रकारों पर निर्भर करता है। इस मामले में, आपके पास unsigned प्रकार और signed प्रकार है जहां unsigned प्रकार signed प्रकार से छोटा है। इस भाव पर सी ++ मानक के अंतर्गत आती है (खंड 5.10 [expr]):

अन्यथा, यदि हस्ताक्षर किए पूर्णांक प्रकार के साथ संकार्य के प्रकार अहस्ताक्षरित साथ संकार्य के प्रकार के मूल्यों के सभी का प्रतिनिधित्व कर सकते पूर्णांक प्रकार, हस्ताक्षरित पूर्णांक प्रकार के साथ ऑपरेंड हस्ताक्षरित पूर्णांक प्रकार के साथ ऑपरेंड के प्रकार में परिवर्तित हो जाएगा।

अर्थात, और अभिव्यक्ति bytesCount + 1 के प्रकार int जो डिफ़ॉल्ट रूप से हस्ताक्षरित किया गया है है।

9

1 एक हस्ताक्षरित शाब्दिक है। बाइट्स काउंटर + 1 यू आज़माएं।

संकलक शायद हस्ताक्षर किए और अहस्ताक्षरित मूल्यों (bytesCount + 1)

3

के अलावा के कारण हस्ताक्षर किए प्रकार की एक अस्थायी मूल्य पैदा कर रही है के बाद से 1 प्रकार int अभिव्यक्ति bytesCount + 1int है की है (हस्ताक्षरित)।

तथ्य जब एक प्रकार int की तुलना में छोटे गणितीय अभिव्यक्ति यह int करने के लिए प्रोत्साहित किया जाता है में प्रयोग किया जाता है, तो भी + bytesCount और bytesCount + bytesCountint माना जाता है और नहीं uint8_t में (जबकि bytesCount + 1U कि जब एक unsigned int है बड़ाint से है) ।

following programtrue आउटपुट तीन बार आउटपुट करता है।

#include <iostream> 

int main() 
{ 
    unsigned short s = 1; 
    std::cout << (&typeid(s + 1U) == &typeid(1U)) << std::endl; 
    std::cout << (&typeid(+ s) == &typeid(1)) << std::endl; 
    std::cout << (&typeid(s + s) == &typeid(1)) << std::endl; 
} 
1

अन्य उत्तरों पहले से ही आपको बताते हैं कि bytesCount + 1 को signed int के रूप में व्याख्या किया गया है। हालांकि, मैं इसे bytesCount == idx में जोड़ना चाहता हूं, bytesCountभीsigned int के रूप में व्याख्या किया गया है। संकल्पनात्मक रूप से, इसे पहले signed int में परिवर्तित कर दिया गया है, और इसके बाद इसे केवल unsigned int में परिवर्तित कर दिया गया है। आपका कंपाइलर इसके बारे में चेतावनी नहीं देता है, क्योंकि इसमें पर्याप्त जानकारी है कि वास्तव में कोई समस्या नहीं है। signed int पर रूपांतरण संभवतः bytesCount नकारात्मक नहीं बना सकता है।bytesCount + 1 की तुलना करना समान रूप से मान्य है, समान रूप से सुरक्षित है, लेकिन संकलक बनाने के लिए बस थोड़ा सा जटिल इसे सुरक्षित के रूप में नहीं पहचानता है।

+0

और संकलक को इस तरह की समस्या के बारे में चेतावनी देने के लिए कैसे कहें, अगर यह प्रोग्राम कोड से स्पष्ट है कि तुलना सुरक्षित है, लेकिन मैं पूरी फ़ाइल के लिए चेतावनियां अक्षम नहीं करना चाहता, और मैं कोड बदसूरत नहीं करना चाहता इससे बचने के लिए। क्या इसे प्राप्त करने के किसी भी तरीके मौजूद हैं? – Arkady

+0

@Arkady यदि संकलक कोड के लिए चेतावनी देने के लिए कॉन्फ़िगर किया गया है, तो आप कोड को बदलना नहीं चाहते हैं (क्योंकि यह उलझन में होगा), और आप कंपाइलर की कॉन्फ़िगरेशन को बदलना नहीं चाहते हैं (क्योंकि यह उपयोगी दबाएगा चेतावनियां भी), आप बहुत सारे विकल्प नहीं खोल रहे हैं। एकमात्र विकल्प मैं सोच सकता हूं कि आपने अभी तक इनकार नहीं किया है, इसके विश्लेषण में सुधार करने के लिए कंपाइलर पर हैकिंग है। – hvd

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