2008-10-15 29 views
6

मुझे वीएसएनईटी और जीसीसी के लिए मेरा कोड चेतावनी मुक्त होना पसंद है, और मुझे अपना कोड 64-बिट तैयार करना पसंद है।size_t जोड़ों में ओवरफ्लो

आज मैंने एक छोटा मॉड्यूल लिखा जो स्मृति बफर में संबंधित है और फ़ाइल-शैली इंटरफ़ेस के माध्यम से डेटा तक पहुंच प्रदान करता है (उदाहरण के लिए आप बाइट्स पढ़ सकते हैं, बाइट लिख सकते हैं, आसपास की तलाश कर सकते हैं)।

वर्तमान पढ़ने की स्थिति और आकार के डेटा-प्रकार के रूप में मैंने size_t का उपयोग किया क्योंकि यह सबसे प्राकृतिक विकल्प प्रतीत होता है। मैं चेतावनियों के चारों ओर मिलता हूं और इसे 64-बिट में भी काम करना चाहिए।

शायद ज़रुरत पड़े: मेरी संरचना इस तरह दिखता है:

typedef struct 
{ 
    unsigned char * m_Data; 
    size_t   m_CurrentReadPosition; 
    size_t   m_DataSize; 
} MyMemoryFile; 

size_t की signedness व्यवहार में परिभाषित किया जा करने के लिए नहीं लगता है। एक Google कोड-सर्च ने साबित किया।

अब मैं एक दुविधा में हूं: मैं ओवरफ्लो के लिए size_t के साथ जोड़ों को देखना चाहता हूं क्योंकि मुझे उपयोगकर्ता द्वारा प्रदान किए गए डेटा से निपटना होगा और तृतीय पक्ष पुस्तकालय मेरे कोड का उपयोग करेंगे। हालांकि, ओवरफ्लो चेक के लिए मुझे साइन-नेस जानना है। यह कार्यान्वयन में एक बड़ा अंतर बनाता है।

तो - कैसे मुझे प्लेटफॉर्म और कंपाइलर स्वतंत्र तरीके से ऐसे कोड को लिखना चाहिए?

क्या मैं size_t पर हस्ताक्षर या संकलन समय पर हस्ताक्षर की जांच कर सकता हूं? इससे मेरी समस्या हल हो जाएगी। या शायद size_t पहली जगह में सबसे अच्छा विचार नहीं था।

कोई विचार?

EDIT: मैं सी-भाषा के लिए समाधान ढूंढ रहा हूं!

+0

आप किस जीसीसी का उपयोग कर रहे हैं? ऐसा लगता है कि उन्होंने 2.4 –

+0

समेत संस्करणों में आकारहीन नहीं किया है और जिन संस्करणों के साथ मुझे निपटना है, वे सभी जगह पर हैं। मैं एम्बेडेड प्रोग्रामिंग करता हूं और कभी-कभी मुझे पत्थर-युग से कंपाइलर संस्करणों का उपयोग करना पड़ता है। –

+0

"हस्ताक्षर" सामान्य शब्द है। – Lassi

उत्तर

11

के बारे में है कि क्या size _t पर हस्ताक्षर किए या अहस्ताक्षरित और जीसीसी है (एक पुरानी जीसीसी पुस्तिका से - मैं नहीं यकीन है कि अगर यह अभी भी वहाँ हूँ):

size_t प्रकार के साथ एक संभावित समस्या है और 2.4 रिलीज करने के लिए जीसीसी के के संस्करण। एएनएसआई सी की आवश्यकता है कि size_t हमेशा एक हस्ताक्षरित प्रकार हो। मौजूदा सिस्टम ' हेडर फाइल के साथ संगतता के लिए, जीसीसी size_t stddef.h में परिभाषित करता है जो कुछ भी प्रकार सिस्टम के sys/types.h जा को परिभाषित करता हो। अधिकांश यूनिक्स सिस्टम size_tsys/types.h में परिभाषित करते हैं, इसे पर हस्ताक्षर किए गए प्रकार पर परिभाषित करें। लाइब्रेरी में कुछ कोड size_t पर हस्ताक्षरित प्रकार होने पर निर्भर करता है, और हस्ताक्षर किए जाने पर सही तरीके से काम नहीं करेगा।

जीएनयू सी लाइब्रेरी कोड जो size_t को हस्ताक्षर किए जाने की अपेक्षा करता है वह सही है। size_t की परिभाषित प्रकार के रूप में परिभाषा गलत है। हम योजना है कि संस्करण 2.4 में, जीसीसी हमेशा size_t एक अहस्ताक्षरित प्रकार के रूप में परिभाषित करेगा, और 'fixincludes' स्क्रिप्ट इस के साथ सिस्टम के sys/types.h इतनी के रूप में नहीं करने के लिए संघर्ष की मालिश होगा।

इस बीच, हम स्पष्ट रूप से को जीसीसी बताकर इस समस्या को हल करने size_t जब GNU सी पुस्तकालय संकलन के लिए एक अहस्ताक्षरित प्रकार का उपयोग करें। 'कॉन्फ़िगर' स्वचालित रूप से का पता लगाएगा size_t के लिए जीसीसी का उपयोग किस प्रकार आवश्यक है यदि आवश्यक हो तो इसे ओवरराइड करें।

आप size_t उपयोग ptrdiff_t की या कुछ सिस्टम पर एक हस्ताक्षरित संस्करण चाहते हैं वहाँ ssize_t के लिए एक typedef है।

+1

वाह! धन्यवाद के लिए बहुत कुछ धन्यवाद इस मुद्दे का इतिहास। –

+2

इसे अपनी जिज्ञासा के लिए करना था - मुझे यह विश्वास करना मुश्किल था कि जीसीसी मानक के एक सुंदर मूल भाग को बिना किसी स्पष्टीकरण के अवहेलना करेगा। –

4

size_t को हस्ताक्षर नहीं किया जाना चाहिए।

इसे आमतौर पर हस्ताक्षरित लंबे समय के रूप में परिभाषित किया जाता है।

मैंने कभी इसे अन्यथा परिभाषित नहीं देखा है। ssize_t इसके हस्ताक्षरित समकक्ष है।

संपादित करें: जीसीसी इसे कुछ परिस्थितियों में हस्ताक्षरित के रूप में परिभाषित करता है। एएसएनआई सी मोड या एसडीडी 99 में संकलन करना इसे हस्ताक्षरित करने के लिए मजबूर होना चाहिए।

+0

जीसीसी ने हस्ताक्षर के रूप में size_t को परिभाषित किया है :( –

+0

64 बिट विंडोज़ में 32 बिट्स को असाइन नहीं किया गया है? आकार_t – ejgottl

+0

g ++ 4.2.3 के लिए अच्छी धारणा नहीं है, इसे बिना हस्ताक्षरित के रूप में परिभाषित किया गया है। – ejgottl

0

safeint का उपयोग करें। यह माइकल हावर्ड द्वारा डिजाइन की गई एक कक्षा है और माइक्रोसॉफ्ट से ओपन सोर्स के रूप में जारी की गई है। यह पूर्णांक के साथ काम करने के लिए डिज़ाइन किया गया है जहां अतिप्रवाह को जोखिम के रूप में पहचाना जाता है। सभी अतिप्रवाह अपवादों में परिवर्तित हो जाते हैं और संभाले जाते हैं। कक्षा को सही उपयोग को आसान बनाने के लिए डिज़ाइन किया गया है।

उदाहरण के लिए:

char CouldBlowUp(char a, char b, char c) 
{ 
    SafeInt<char> sa(a), sb(b), sc(c); 

    try 
    { 
    return (sa * sb + sc).Value(); 
    } 
    catch(SafeIntException err) 
    { 
     ComplainLoudly(err.m_code); 
    } 

    return 0; 
} 

इसके अलावा safeint कार्यालय जैसे उत्पादों में माइक्रोसॉफ्ट पर आंतरिक रूप से एक बहुत प्रयोग किया जाता है।

रेफरी:

temp = value_to_be_added_to; 

value_to_be_added_to += value_to_add; 

if (temp > value_to_be_added_to) 
{ 
    overflow... 
} 

चूंकि यह कम मानों आप आसानी से देख सकते करने के लिए वापस लपेट होगा: link text

+0

मैं SaveInt का उपयोग नहीं कर सकता। मैं केवल सी हूं, और afaik saveint साइन-नेस समस्या को हल नहीं करता है क्योंकि यह msvc से डिफ़ॉल्ट मानता है। –

+0

ओह ठीक है प्रश्न को प्रारंभ में सी ++ के रूप में चिह्नित किया गया था। सी भाषा लाइब्रेरी के लिए मेरा दूसरा उत्तर देखें। –

+0

हाँ - मुझे पता है। इसके बारे में क्षमा करें। मैंने यह सुनिश्चित करने के लिए प्रश्न संपादित किया कि मैं गुमराह नहीं करता कोई और। –

0

मुझे यकीन है कि अगर मैं सवाल वास्तव में समझते हैं, लेकिन हो सकता है आप की तरह कुछ कर सकते हैं नहीं कर रहा हूँ अगर यह बह गया है।

+0

क्या होगा यदि value_to_add नकारात्मक है? –

+0

इसके विपरीत जांचें। –

2

सी भाषा के लिए, IntSafe का उपयोग करें। माइक्रोसॉफ्ट द्वारा भी जारी किया गया (सी ++ लाइब्रेरी सेफिंट के साथ भ्रमित नहीं होना चाहिए)। IntSafe सी भाषा फ़ंक्शन कॉल का एक सेट है जो गणित कर सकता है और रूपांतरण सुरक्षित रूप से कर सकता है। updated URL for intsafe functions

4

size_t सी ++ सी मानकों के अनुसार एक हस्ताक्षरित अभिन्न प्रकार है। size_t पर हस्ताक्षर किए गए किसी भी कार्यान्वयन गंभीर रूप से गैर-अनुरूप है, और शायद अन्य पोर्टेबिलिटी समस्याएं भी हैं। ओवरफ्लोइंग के दौरान चारों ओर लपेटने की गारंटी है, जिसका अर्थ है कि आप ओवरफ्लो खोजने के लिए if (a + b < a) जैसे परीक्षण लिख सकते हैं।

size_t स्मृति से जुड़ी कुछ भी के लिए एक उत्कृष्ट प्रकार है। आप इसे सही कर रहे हैं।

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