2017-02-11 6 views
5

उदाहरण के लिए, निम्नलिखित समारोह कानूनी है:निरंतर सदस्यों के साथ गंतव्य संरचना के साथ memcpy का उपयोग करना कानूनी है?

struct two_int { 
    const int a, b; 
} 

void copy_two(const two_int *src, two_int *dest) { 
    memcpy(dest, src, sizeof(two_int)); 
} 

यह कम से कम निरंतर परिभाषित मूल्यों के संशोधनों में से कुछ प्रकार की अनुमति नहीं है की तरह लगता है, लेकिन यह है कि अगर यह उत्तीर्ण मेरे लिए स्पष्ट नहीं है।

अगर जवाब "यह नहीं, सामान्य रूप में अनुमति दी है", मैं भी विशेष मामले में जहां dest नव malloc के साथ स्मृति आवंटित किया जाता है के बारे में सोच रहा हूँ (और इसलिए अभी तक कोई मूल्य सौंपा नहीं किया गया है), जैसे:

two_int s = {.a = 1, .b = 2}; 
two_int *d = malloc(sizeof(two_int)); 
copy_two(&s, d); 

अद्यतन: ऐसा लगता है उत्तरार्द्ध सवाल (यह ठीक है) सकारात्मक जवाब के लिए एक नव malloc 'घ संरचना के मामले के लिए लगता है, लेकिन मूल, अधिक सामान्य प्रश्न अभी भी खड़ा है , मुझे लगता है।

+4

नहीं। स्थिर चर को संशोधित करने का प्रयास * कहीं भी * अपरिभाषित व्यवहार * है। –

+2

इसका तात्पर्य है कि 'm_oc' _ mveroc' या अन्यथा गतिशील रूप से आवंटित किया जा सकता है, है ना? चूंकि आप किसी भी निर्माण जानकारी को 'malloc' पर पास नहीं कर सकते हैं ... – SODIMM

+1

यह प्रश्न [भाषा-वकील] टैग के लिए अर्हता प्राप्त कर सकता है। –

उत्तर

0

ऐसे उद्देश्यों के लिए memcpy का उपयोग केवल तभी परिभाषित किया जाएगा जब वास्तविक गंतव्य ऑब्जेक्ट में स्थैतिक या स्वचालित अवधि न हो।

struct foo { double const x; }; 
void outsideFunction(struct foo *p); 

double test(void) 
{ 
    struct foo s1 = {0.12345678}; 
    outsideFunction(&s1); 
    return 0.12345678; 
} 

एक संकलक करने के लिए समारोह का अनुकूलन करने के हकदार हो जाएगा::

कोड को देखते हुए

double test(void) 
{ 
    static struct foo const s1 = {0.12345678}; 
    outsideFunction(&s1); 
    return s1.x; 
} 

कई प्रोसेसर पर, एक ही रास्ता एक मनमाना लगातार करने के लिए है के साथ एक डबल लोड करने के लिए उस ऑब्जेक्ट को ऑब्जेक्ट होल्डिंग से लगातार लोड करें, और इस मामले में कंपाइलर आसानी से एक ऑब्जेक्ट (s1.x) को जानता है जिसमें स्थिर 0.12345678 होना चाहिए। शुद्ध प्रभाव वह कोड होगा जो memcpys1.x पर लिखने के लिए संख्यात्मक स्थिर 0.12345678 के अन्य उपयोगों को दूषित कर सकता है। जैसा कह रहा है, "चर नहीं होंगे; स्थिरांक नहीं हैं"। बुरा सामान।

समस्या आवंटित अवधि की वस्तुओं के लिए मौजूद नहीं होगी क्योंकि memcpy को किसी भी "प्रभावी प्रकार" सहित गंतव्य संग्रहण में संग्रहीत के बारे में सबकुछ "भूलना" की आवश्यकता होती है। स्थाई और स्वचालित वस्तुओं के घोषित प्रकार उनमें से किसी भी चीज़ से स्वतंत्र होते हैं, और उन्हें "memcpy" और किसी अन्य माध्यम से मिटाया नहीं जा सकता है, लेकिन आवंटित अवधि की वस्तुओं में केवल "प्रभावी प्रकार" होता है जो मिटा दिया जाएगा।

+0

यह एक वैध उदाहरण है, लेकिन क्या यह सामान्य समस्या का एक विशेष मामला नहीं है? यदि आप ऐसे structs को बहिष्कृत करते हैं जिनमें केवल कॉन्स सदस्य होते हैं, तो क्या यह कॉपी करने योग्य हो सकता है? – jxh

+0

@jxh: मैंने एक और जटिल उदाहरण के साथ शुरुआत की जो उस मामले में विफल हो जाएगी। मान लीजिए कि 'स्ट्रक्चर फू' में निरंतर सदस्य थे, लेकिन फ़ंक्शन ने 'v'' शुरू किया, 'v1.x' को' v + 0.12345678' में प्रारंभ किया, और फिर 'v + 0.12345678' लौटा दिया। कंपाइलर यह ध्यान देने योग्य होगा कि 's1.x' में मान ठीक से मेल खाता है जो इसे वापस करने के लिए आवश्यक है, और इस प्रकार उस मान को लोड करता है। मैं 'const' का एक मजबूत रूप रखने के लिए उपयोगिता देख सकता था जो वादा करता है कि यदि कोई कोड किसी ऑब्जेक्ट के मान को पढ़ता है, तो उस ऑब्जेक्ट के किसी भी बाद में * उस पॉइंटर का उपयोग करके पढ़ा जाता है ... – supercat

+0

... बिना किसी ऑब्जेक्ट के पते से किसी भी प्रकार के रूपांतरण * एक ही मूल्य उत्पन्न करेंगे, लेकिन यह पहचानने की आवश्यकता होगी कि प्रकार के रूपांतरणों को एक सूचक के लक्ष्य के बारे में एक कंपाइलर की धारणाओं को प्रभावित करना चाहिए। मुझे लगता है कि यह स्पष्ट होगा कि उन्हें चाहिए, लेकिन जीसीसी जैसे कंपाइलरों के डिजाइन से यह मुश्किल हो जाएगा। – supercat

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