2017-06-04 16 views
8
#define LENGTH 6 
typedef char data_t[LENGTH]; 
struct foo { 
    const data_t data; 
    ... 
} 
... 
void bar(data_t data) { 
    printf("%.6s\n", data); 
    struct foo myfoo = {*data}; 
    printf("%.6s\n", foo.data); 
} 

अंदर एक स्थिरांक सरणी आरंभ किया जा रहा है कि मैं इस struct जो सीधे डेटा मैं में, sizeof(foo) == 6+the rest, नहीं sizeof(foo) == sizeof(void*)+the rest इच्छुक हूँ धारण करने की कोशिश कर रहा हूँ। हालांकि मुझे की data_t के साथ एक स्ट्रक्चर प्रारंभ करने का कोई तरीका नहीं मिल रहा है। मुझे लगता है कि शायद मैं क्षेत्र से const संशोधक को हटा सकता हूं और memcpy का उपयोग कर सकता हूं लेकिन मुझे अतिरिक्त सुरक्षा और स्पष्टता पसंद है।एक struct

मैं नहीं मिलता है किसी भी त्रुटि संकलन लेकिन जब मैं कोड चल रहा

123456 
1?? 

तो प्रतिलिपि काम नहीं किया पाने के लिए ठीक से मुझे लगता है।

यह एक आर्डिनो (या इसी तरह की डिवाइस) के लिए है, इसलिए मैं इसे बहुत पोर्टेबल कोड में रखने की कोशिश कर रहा हूं।

क्या यह संभव नहीं है?

संपादित करें: data_t फ़ील्ड पर const संशोधक को हटाने में मदद नहीं मिलती है।

+3

कठिनाई यह है कि तर्क 'डेटा_टी डेटा' 'char * डेटा' के बराबर है, और इसके आस-पास एक आसान तरीका नहीं है जिसे मैं सोने के समय के ढाई घंटे के बारे में सोच सकता हूं। सी, निश्चित रूप से प्रत्यक्ष सरणी असाइनमेंट का समर्थन नहीं करता है। क्या आप 'स्ट्रक्चर फू *' को 'बार' में पास कर सकते हैं? फिर यह आसान है: 'संरचना foo foo = * डेटा; '। –

+2

टाइपिफ़ को टाइप नहीं किया जाना चाहिए 'typedef char data_t [LENGTH]; '? और 'struct foo = {* data};' मेरे लिए मान्य नहीं दिखता है ... – InternetAussie

+2

'struct foo f {.data = {data [0], डेटा [1], डेटा [2], डेटा [3] , डेटा [4], डेटा [5]}} ' – dasblinkenlight

उत्तर

0

Eehh I kinda एक समाधान मिला। यह थोड़ा मूर्ख है लेकिन जो कुछ भी

void bar(data_t data) { 
    struct foo myfoo = {0, ...}; // don't initialize the `data` yet, on purpose 
    memcpy((void*)&foo.data, data, LENGTH); 
} 

यह कोई चेतावनी नहीं देता है और मुझे मैदान पर स्थिरता मिलती है। मुझे पता है कि यह तकनीकी रूप से memcpy को उस क्षेत्र में ठीक नहीं है जिसे कॉन्स्ट माना जाता है लेकिन इस मामले में मैं केवल उस कार्य में इसे कर रहा हूं जो संरचना को प्रारंभ करता है। यह भी लगता है कि सरणी एक सूचक नहीं है लेकिन वास्तव में पूरी तरह से foo संरचना (कोई सूचक, yay)

यदि मैं कोई भी देने के इच्छुक हूं तो भी मुझे प्रतिक्रिया पसंद आएगी।

+3

यदि ऑब्जेक्ट मूल रूप से घोषित किया गया है, तो यह ऑब्जेक्ट काम करने की संभावना है यदि संपूर्ण ऑब्जेक्ट स्थिर और स्थैतिक नहीं है, हालांकि यह अवैध है। ऑब्जेक्ट मूल रूप से घोषित होने पर एक बिंदु-वस्तु को स्थिर करने की स्थिति को दूर नहीं किया जाना चाहिए। – PSkocik

1

मानक अनुपालन में ऐसा करना असंभव है।

अपने जा रहा है const के कारण, const char data[6]; या प्रयोग करने योग्य होने के लिए शुरू किया जाना चाहिए, और यह केवल (कोई प्रारंभकर्ता के साथ स्थिर वस्तुओं स्वचालित रूप से ध्यान केंद्रित किया है) स्थिर प्रारंभ किया जा सकता है, एक स्ट्रिंग शाब्दिक के साथ, एक ब्रेस के साथ -निर्धारित प्रारंभकर्ता सूची। आप इसे पॉइंटर या किसी अन्य सरणी के साथ प्रारंभ नहीं कर सकते हैं।

अगर मैं तुम्हें थे, मैं const से छुटकारा पाने के हैं, दस्तावेज़ कि .data बदल नहीं किया जाना चाहिए के बाद प्रारंभ, और उसके बाद memcpy का उपयोग यह प्रारंभ करने में।

(const संरचना सदस्यों पर बहुत अच्छी तरह से काम नहीं करता है। यह प्रभावी रूप से आपको प्रारंभिक कार्य करने में सक्षम होने से रोकता है, और सी ++ अपने कन्स्ट्रक्टर कार्यों के लिए विशेष भाषा समर्थन करके समस्या को हल करता है , समस्या तब भी बनी हुई है जब const सदस्य सरणी हैं)।

1

कुछ लागत >=0 के लिए ऐसा करना संभव है।

typedef struct 
{ 
    char c[LENGTH]; 
} data_t; // this struct is freely copyable 

struct foo 
{ 
    const data_t data; // but this data member is not 
    int what; 
}; 

void foo (char* x) { 
    data_t d;       // declare freely copyable struct instance 
    memcpy(d.c, x, sizeof(d.c));  // memcpy it 
    struct foo foo = { d, 42 };  // initialise struct instance with const member 
    ... 
}; 

कुछ कंपाइलर (उदा।बजना) भी x से d.c के लिए और फिर d से foo.data सीधे foo.data को x से ⇒ करने के लिए) (अनावश्यक नकल दूर अनुकूलन करने के लिए सक्षम हैं। अन्य (जीसीसी मैं आपको देख रहा हूं) ऐसा करने में सक्षम नहीं लगता है।

यदि आप सीधे data_t पर पॉइंटर्स को char पॉइंटर्स के बजाय पास करते हैं, तो आपको इस अतिरिक्त memcpy चरण की आवश्यकता नहीं होगी। foo के अंदर char सरणी तक पहुंचने के लिए ओटीओएच आपको केवल .data की बजाय सदस्य स्तर (.data.c) की आवश्यकता है; इसमें कोई रनटाइम लागत नहीं है)।

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