2008-09-26 25 views
35

मैं कोड का एक टुकड़ा ढूंढ रहा हूं जो मुझे संरचना के एक उदाहरण आवंटित किए बिना संरचना के भीतर किसी क्षेत्र के ऑफसेट को बता सकता है।सी/सी ++ संरचना ऑफ़सेट

आईई: दी

struct mstct { 
    int myfield; 
    int myfield2; 
}; 

मैं लिख सकते हैं:

mstct thing; 
printf("offset %lu\n", (unsigned long)(&thing.myfield2 - &thing)); 

और मिल उत्पादन के लिए "ऑफसेट 4"। मैं इसे "mstct चीज़" घोषणा/आवंटित किए बिना कैसे कर सकता हूं?

मुझे पता है कि & < संरचना > संरचना के पहले क्षेत्र के पहले बाइट पर हमेशा इंगित नहीं करता है, मैं इसके बाद के लिए खाता कर सकता हूं।

उत्तर

69

मानक ऑफसेट() मैक्रो (stddef.h में) के बारे में कैसे?

संपादित करें:

#define OFFSETOF(type, field) ((unsigned long) &(((type *) 0)->field)) 
+1

मुझे जो कुछ चाहिए था, उतना नहीं, क्योंकि मेरे पास stddef.h नहीं है, लेकिन यह मेरे प्रश्न का उत्तर देता है: #define ऑफसेट (प्रकार, सदस्य) ((size_t) और ((प्रकार *) 0) -> सदस्य) – davenpcj

+3

वाह - कोई stddef.h? जिज्ञासा से बाहर, क्या मैं पूछ सकता हूं कि आप क्या उपयोग कर रहे हैं? –

+0

यह सी 99 मानक में है, इसलिए मैं एक नया संकलक प्राप्त करने का सुझाव दूंगा। – wnoise

8

ठीक है, का उपयोग offsetof मैक्रो, जो (कम से कम के साथ: लोग हैं, जो किसी कारण से offsetof() मैक्रो उपलब्ध नहीं हो सकता है, आप की तरह कुछ का उपयोग कर प्रभाव प्राप्त कर सकते हैं

offsetof(struct mstct, myfield2) 
+0

ऑफ़सेट() पहले एएनएसआई सी 8 9 मानक के बाद मानक सी/सी ++ में रहा है। प्रत्येक कंपाइलर को यह होना चाहिए, जब तक कि आप कुछ गंभीरता से प्राचीन का उपयोग नहीं कर रहे हों। इसके बावजूद इसे बदसूरत कास्टिंग और पॉइंटर अंकगणित का उपयोग करके एक साथ जोड़ा जा सकता है। –

+0

सहमत - मैं मैक्रोज़ प्रदान करने के लिए सबसे अधिक संभावना एक डमी प्रदान करता हूं। प्लोगर "मानक सी लाइब्रेरी" प्रदान करता है और यह प्रदान करने के लिए एक आसान हेडर है - जब तक इसे पोर्टेबल नहीं होना चाहिए। –

+0

AFAIK, offsetof() हिंग नहीं है * लेकिन * बदसूरत कास्टिंग और पॉइंटर अंकगणित ... कुछ ऐसा है: # ऑफसेट (ऑफसेट, फ़ील्ड) ((char *) और (((टाइप *) 0) -> फ़ील्ड) - (char *) 0) –

3

printf ("ऑफसेट::% d \ n", & ((mstct *) 0) जीएनयू सीसी) दोनों C और C++ कोड के लिए उपलब्ध है -> myfield2);

+1

इस तथ्य के अलावा कि 'ऑफसेटोफ़' इसे अधिक पठनीय तरीके से करता है, आप आम तौर पर 'ptrdiff_t' को '% d' के साथ प्रिंट नहीं कर सकते - एलपी 64 सिस्टम पर, यह बहुत बड़ा है। –

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