2014-10-21 7 views
6

मैं एक protobuf-c उदाहरण प्राप्त करने की कोशिश कर रहा हूं जो एक सी 0 9 0 कंपाइलर (एमएस वीएस2012) के साथ संकलित है।शून्य * सरणी * * (शून्य **) सदस्य + siz * (* p_n) का उद्देश्य क्या है;

Protobuf-सी स्रोत कोड के भीतर वहाँ दो C99 विशिष्ट चीजें हैं जो आसानी से C90 के साथ संगत होना करने के लिए बदला जा सकता है, एक गुंजाइश (not allowed in C90) और instantiation of structs. -syntax के माध्यम से के बीच में यानी चर घोषणा (जैसे some_struct_type name = {.a=1,.b=2} हैं)।

अब मैं एक संकलन त्रुटि के साथ अटक गया हूं। स्रोत फ़ाइल 'Protobuf-c.c' में संबंधित लाइन में लिखा है:

void *array = *(void **) member + siz * (*p_n); 

कहाँ membervoid * और p_nsize_t * के रूप में के रूप में परिभाषित है। और संबंधित त्रुटि

error C2036: 'void *' : unknown size 

है कृपया ध्यान दें यह Protobuf-सी संस्करण 1.0.1 (respective source code देखते हैं, लाइन 2404 में) के लिए मान्य है। यह लाइन संस्करण 1.0.2 से

void *array = *(char **) member + siz * (*p_n); 

this comment के साथ बदल दी गई है। तदनुसार लाइन बदलना संकलन त्रुटि को समाप्त करता है।

मेरे प्रश्न हैं:

  • मैं कोड की इस पंक्ति को समझने के लिए चाहते हैं।
  • क्या मैं *(char **) संस्करण पर स्विच कर सकता हूं?
  • त्रुटि संदेश मुझे क्या बता रहा है?

(किसी अन्य कारण से मैं करने के लिए छड़ी करना चाहते हैं Protobuf-सी 1.0.1 के लिए)

+6

ऐसा लगता है कि यह मनुष्यों द्वारा अपठनीय होने के लिए डिज़ाइन किया गया है। :) – Almo

+0

कुछ कंपाइलर्स हैं जो शून्य * कम से कम BYTE * के समान हैं, कम से कम सूचक अंकगणित में। यानी आकार (शून्य *) 1 तक संकलित करता है। मैं इस अव्यवस्था रेखा को इसके तत्वों में विभाजित करता हूं और पॉइंटर अंकगणितीय * के इस विशिष्ट उद्देश्य के लिए 'char *' * द्वारा 'शून्य *' को प्रतिस्थापित करता हूं। – harper

+0

@harper कोड को पढ़ने के लिए क्या होगा यदि यह "de-cluttered" – georg

उत्तर

4

पैरामीटर member के रूप में पारित एक सूचक का एक पता सूचक चार है। सबसे पहले कलाकारों और defererence कि सूचक मिलता है। (सूचक का पता पारित कर दिया है ताकि सूचक समारोह में बदला जा सकता है।)

अतिरिक्त siz * (*p_n) पॉइंटर को सही तत्व में बढ़ाता है।

char** pm = member ; 
char* m = *pm ; 
void *array = m + siz * (*p_n); 

शून्य * से एक परिवर्तन चार करने के लिए * किया जाता है ताकि सूचक अंकगणित संभव है, सी स्टैंडर्ड शून्य संकेत पर यह अनुमति नहीं है के रूप में:

पूरी लाइन के रूप में लिखा जा सकता है। त्रुटि संदेश आपको बता रहा है कि, ऑब्जेक्ट शून्य का आकार * इंगित कर रहा है, वहां आपको char * सूचक का उपयोग करना होगा।

जब तक कार्य को पारित ऑब्जेक्ट में char** टाइप होता है तो आप char ** संस्करण पर स्विच कर सकते हैं।

2

I would like to understand this line of code.

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

Can I switch to the *(char **) version?

हाँ, क्योंकि कोड, जिसके परिणामस्वरूप सूचक प्रदान करती है और सूचक dereferences नहीं है।

What is the error message telling me?

इस हैक संकलक विशिष्ट है। आपका कंपाइलर इसे कम नहीं करता है, यह void* लक्ष्य का आकार प्रदान नहीं करता है।

आपको "पोर्टेबल" संस्करण का उपयोग करना चाहिए। sizeof(char) सबसे compilers के लिए एक है और इन compilers के लिए यह पोर्टेबल है।

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