2008-12-17 9 views
32

क्या एक ही प्रकार के टाइपपीफ के लिए स्पष्ट कलाकारों को लागू करने का कोई तरीका है? मुझे utf8 से निपटना है और कभी-कभी मैं चरित्र गणना और बाइट गिनती के सूचकांक के साथ भ्रमित हो जाता हूं।सी में मजबूत प्रकार की जांच लागू करें (टाइपपीफ के लिए सख्तता टाइप करें)

typedef unsigned int char_idx_t; 
typedef unsigned int byte_idx_t; 

अलावा है कि आप उन दोनों के बीच एक स्पष्ट कलाकारों की जरूरत है:: तो यह कुछ typedefs करना अच्छा हो

char_idx_t a = 0; 
byte_idx_t b; 

b = a; // compile warning 
b = (byte_idx_t) a; // ok 

मुझे पता है कि इस तरह के एक सुविधा सी में मौजूद नहीं है, लेकिन शायद आप एक चाल या एक कंपाइलर एक्सटेंशन (बेहतर जीसीसी) जानते हैं जो ऐसा करता है।


संपादित मैं अभी भी नहीं वास्तव में सामान्य रूप में हंगेरी संकेतन तरह से करते हैं। मैं परियोजना कोडिंग सम्मेलनों की वजह से इस समस्या के लिए इसका उपयोग नहीं कर सका, लेकिन मैंने इसे अब इसी तरह के मामले में इस्तेमाल किया, जहां प्रकार समान हैं और अर्थ बहुत समान हैं। और मुझे स्वीकार करना है: यह मदद करता है। मैं कभी भी "इंट" के साथ हर इंटीजर की घोषणा नहीं करता हूं, लेकिन जोएल के उदाहरण में अतिव्यापी प्रकार के उदाहरण के रूप में, यह जीवन की बचत हो सकता है।

+2

[जोएल] (http://www.joelonsoftware.com/) नाम से [एक और बहुत अच्छा लेख है (हालांकि मैं गोटो पर प्रतिबंध लगाने के लिए सहमत नहीं हूं :)) [गलत कोड देखो गलत] बनाना (http://www.joelonsoftware.com/articles/Wrong.html)। मुझे लगता है कि अगर यह सीधा कनेक्शन नहीं है तो भी यह आपके प्रश्न से बहुत संबंधित है। – Ilya

+0

उस लेख में सबसे दिलचस्प 'और महत्वपूर्ण बात, आईएमएचओ, हंगेरियन नोटेशन के इतिहास के बारे में कुछ है। Veeery दिलचस्प ... – Noein

उत्तर

2

यदि आप सी ++ लिख रहे थे, तो आप अलग-अलग नामों के साथ दो समान रूप से परिभाषित कक्षाएं बना सकते हैं जो एक हस्ताक्षरित int के चारों ओर रैपर थे। मैं सी

में आप क्या चाहते करने के लिए एक चाल के बारे में पता नहीं है
+2

सी structs के साथ एक ही तरह से काम करता है। माइक्रोसॉफ्ट विंडोज़ में हैंडल प्रकारों को अलग करने के लिए इसका उपयोग करता है। –

18

आप की तरह कुछ कर सकता है:

char_idx a; 
byte_idx b; 

b.b_idx = a.c_idx; 

: जब आप प्रत्येक का उपयोग कर रहे

typedef struct { 
    unsigned int c_idx; 
} char_idx; 

typedef struct { 
    unsigned int b_idx; 
} byte_idx; 

तो फिर तुम देखना होगा अब यह और स्पष्ट है कि वे अलग-अलग प्रकार हैं लेकिन अभी भी संकलित होंगे।

18

"संभाल" प्रकार (अपारदर्शी संकेत) के लिए, Microsoft संरचनाओं की घोषणा और फिर संरचना करने के लिए एक सूचक typedef'ing की चाल का उपयोग करता है:

#define DECLARE_HANDLE(name) struct name##__ { int unused; }; \ 
          typedef struct name##__ *name 

तो बजाय

typedef void* FOOHANDLE; 
typedef void* BARHANDLE; 

वे कार्य करें:

DECLARE_HANDLE(FOOHANDLE); 
DECLARE_HANDLE(BARHANDLE); 

तो अब, यह काम करता है:

FOOHANDLE make_foo(); 
BARHANDLE make_bar(); 
void do_bar(BARHANDLE); 

FOOHANDLE foo = make_foo(); /* ok */ 
BARHANDLE bar = foo;   /* won't work! */ 
do_bar(foo);     /* won't work! */ 
7

एक लिंट का उपयोग करें। Splint:Types और strong type check देखें।

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

4

सी में, केवल उपयोगकर्ता परिभाषित प्रकार कि है संकलक द्वारा लागू के बीच भेद structs के बीच अंतर है। अलग-अलग structs शामिल कोई typedef काम करेगा। आपका प्रमुख डिजाइन प्रश्न है विभिन्न संरचना प्रकारों को समान सदस्य नामों का उपयोग करना चाहिए? यदि ऐसा है, तो आप मैक्रोज़ और अन्य स्कर्वी चाल का उपयोग करके कुछ पॉलीमोर्फिक कोड अनुकरण कर सकते हैं। यदि नहीं, तो आप वास्तव में दो अलग-अलग प्रतिनिधित्वों के लिए प्रतिबद्ध हैं। जैसे, आप byte_idx और char_idx दोनों पर INCREMENT का उपयोग

#define INCREMENT(s, k) ((s).n += (k)) 

करने में सक्षम हो सकता है और करना चाहते हैं? फिर फ़ील्ड को समान रूप से नाम दें।

3

आपने एक्सटेंशन के बारे में पूछा। जेफ फोस्टर का CQual बहुत अच्छा है, और मुझे लगता है कि यह वह काम कर सकता है जो आप चाहते हैं।

+0

क्या ऐसे ही प्रोग्राम हैं जो अभी भी सक्रिय हैं (सीक्यूएल के वेबपृष्ठ का अंतिम अपडेट 2004 में था) – CodeMonkey

14

जो आप चाहते हैं उसे "मजबूत टाइपपीफ" या "सख्त टाइपिफ़" कहा जाता है।

कुछ प्रोग्रामिंग भाषाओं [जंग, डी, हास्केल, एडा, ...] भाषा स्तर पर इसके लिए कुछ समर्थन देते हैं, सी [++] नहीं। इसे "ओपेक टाइपपीफ" नाम से भाषा में शामिल करने का एक प्रस्ताव था, लेकिन इसे स्वीकार नहीं किया गया था।

भाषा समर्थन की कमी वास्तव में कोई समस्या नहीं है। टाइप प्रकार के बिल्कुल 1 डेटा सदस्य वाले एक नए वर्ग में अलियाकृत होने के लिए बस प्रकार को लपेटें। पुनरावृत्ति के अधिकांश टेम्पलेट्स और मैक्रोज़ द्वारा फैक्टर किए जा सकते हैं। यह सरल तकनीक सीधे समर्थन के साथ प्रोग्रामिंग भाषाओं में उतनी ही सुविधाजनक है।

2

उपयोग मजबूत typedef BOOST_STRONG_TYPEDEF

+3

बूस्ट एक सी ++ लाइब्रेरी है, और इसलिए अप्रासंगिक है। – Porculus

1

में परिभाषित के रूप में सी ++ 11 आप एक enum वर्ग का उपयोग कर सकते हैं, उदाहरण के साथ

enum class char_idx_t : unsigned int {}; 
enum class byte_idx_t : unsigned int {}; 

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

+0

प्रस्ताव संशोधन देखें (3) http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf – qub1n

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