2011-01-04 9 views
15

मैं एक बड़ी परियोजना पर काम कर रहा हूं जो आम तौर पर ठीक काम करता है, लेकिन इनपुट डेटा आकार कुछ सीमाओं से अधिक होने के बाद गंभीर समस्याएं दिखाता है।एक सी प्रोग्राम में (सभी) पूर्णांक ओवरफ्लो कैसे ढूंढें?

इन मुद्दों (संदिग्ध) कर रहे हैं केवल हस्ताक्षर किए पूर्णांक के कारण इस तरह के overflows:

int a, o; 
// Initialize a and o 
int x = (a+o) >> 1); 

जाहिर है, एक का योग और ओ अतिप्रवाह (2^31-1 से भी बड़ा हो जाता है) एक बार, एक्स नहीं है एक और ओ का मतलब लंबा है।

क्या चल रहे कार्यक्रम में इन सभी पूर्णांक ओवरफ़्लो को खोजने का कोई सामान्य तरीका है?

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

मुझे पता है, ओवरफ्लो के लिए एक अंकगणितीय निर्देश की जांच कैसे करें (उदाहरण के लिए साइन के लिए साइन जांचना), हालांकि बड़ी मात्रा में कोड के कारण, यह मेरे लिए पूरी परियोजना के माध्यम से जाने और जांच डालने के लिए व्यवहार्य समाधान नहीं है हाथ से हर जगह कोड।

उत्तर

3

बड़े कोड बेस के लिए, Coverity एक अच्छा है उपकरण। मुझे यकीन नहीं है कि यह all पूर्णांक ओवरफ़्लो का पता लगाएगा या नहीं, लेकिन इसका प्रयास करने लायक है।

2

आपको सभी कोड के माध्यम से काम करना होगा और उपयोगकर्ता-इनपुट पर सीमा क्या है और इनपुट को मान्य करें। ओवरफ्लो समस्याओं को कम करने के लिए आपको कुछ एल्गोरिदम फिर से लिखने की आवश्यकता हो सकती है।

जैसा कि आप देते हैं उदाहरण नकारात्मक मानों के लिए काम नहीं करता है, आपको किसी भी तरह से unsigned int का उपयोग करना चाहिए, जिससे आप पहले से ही परिमाण का अतिरिक्त क्रम दे सकते हैं।

संपादित करें: जीसीसी -ftrapv का विकल्प है, लेकिन इस आमतौर पर वास्तव में कुछ भी केवल -O0 साथ काम करता है नहीं करता है। यदि आप होने पर ओवरफ्लो फँसाने का दृष्टिकोण ले रहे हैं, तो आपको पूरी तरह से परीक्षण करने के लिए कोड के अच्छे ज्ञान की आवश्यकता है।

+0

मुझे लगभग पता है कि उपयोगकर्ता इनपुट की सीमा क्या है। कोड के माध्यम से काम करने में समस्या यह है कि इस परियोजना में 200k से अधिक लाइनें हैं (उनमें से 199k मेरे द्वारा लिखी नहीं गई हैं) और मुझे डर है कि ओवरफ्लो-प्रोन कोड के लिए उन्हें हाथ से जांचना बहुत असंभव होगा। – ChrisM

+0

@ChrisM - यदि आप ऐसी स्थिति में हैं जहां आप उस कोड पर भरोसा नहीं कर सकते हैं तो किसी और ने लिखा है सही है तो आपको शायद इसका उपयोग नहीं करना चाहिए। इस तरह की चीजों से निपटने के लिए व्यवसाय प्रथाएं होनी चाहिए (समीक्षा, परीक्षण, आदि)। यदि यह सिर्फ आप इस कोड के साथ है और किसी और के आसपास नहीं है, तो आपको वैसे भी इसे पढ़ने के लिए कुछ समय बिताने की आवश्यकता होगी। – OrangeDog

+0

ठीक है, यह एक दयालु है। मुझे उम्मीद थी कि कोड में समस्याग्रस्त वर्गों को खोजने का कोई तरीका था (शायद एक दर्जन, या कुछ और)। – ChrisM

0

कैसे एक स्क्रिप्ट जो कोड के माध्यम से चला जाता है और की जगह के बारे में सभी "ए + बी" DEBUGADD साथ (ए, बी) - जहां कर सकते हैं:

#ifdef DEBUG 
int addFn(int a, int b) { 
    long long m; 
    int n; 
    m = (long long)a + (long long)b; 
    n = a + b; 
    if (m != (long long)n) 
    printf("PANIC!\n"); 
    return n; 
} 
#define DEBUGADD(a,b) addFn(a,b) 
#else 
#define DEBUGADD(a,b) ((a)+(b)) 
#endif 
+3

बस सुनिश्चित करें कि आपकी स्क्रिप्ट व्हाइटस्पेस, कास्ट, संचालन के क्रम, और सही प्रकारों को सही तरीके से संभालती है :) – Karmastan

+0

बेहतर होगा 'जोर दें (((एक <= 0) || (बी <= INT_MAX - ए)) && ((ए> = 0) || (बी> = INT_MIN - ए))) ', चूंकि एक समान अभिव्यक्ति' long' और 'long long' के लिए भी काम करेगी। – caf

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