c++ - क्या एक पॉइंटर के लिए एक पॉइंटर को एक पॉइंटर के माध्यम से एक अलग, असंबंधित सबबॉजेक्ट के लिए पॉइंटर प्राप्त करना संभव है?



pointers language-lawyer (1)

इस सरल कोड को देखें:

struct Point {
    int x;
    int y;
};

void something(int *);

int main() {
    Point p{1, 2};

    something(&p.x);

    return p.y;
}

मुझे उम्मीद है, कि main वापसी मूल्य return 2; लिए अनुकूलित किया जा सकता है return 2; , क्योंकि something पास py तक पहुँच नहीं है, यह केवल px को पॉइंटर देता है।

लेकिन, प्रमुख कंपाइलरों में से कोई भी main के रिटर्न वैल्यू को 2 ऑप्टिमाइज़ नहीं करता है। Godbolt

क्या मानक में कुछ है, जो py को संशोधित करने की अनुमति देता something , अगर हम केवल px तक पहुंच देते हैं? यदि हाँ, तो क्या यह इस बात पर निर्भर करता है कि Point में मानक लेआउट है या नहीं?

क्या होगा यदि मैं something(&p.y); उपयोग करता हूं something(&p.y); , और return px; बजाय?


यह पूरी तरह से परिभाषित है:

void something(int *x) {
    reinterpret_cast<Point*>(x)->y = 42;
}

Point ऑब्जेक्ट ( p ) और इसके x सदस्य पॉइंटर-इंटरकनेक्टेबल हैं, [basic.compound] :

दो ऑब्जेक्ट्स a और b पॉइंटर-इंटरकनेक्टेबल हैं यदि:

  • [...]
  • एक मानक-लेआउट वर्ग ऑब्जेक्ट है और दूसरा उस ऑब्जेक्ट का पहला गैर-स्थिर डेटा सदस्य है, या, यदि ऑब्जेक्ट में कोई गैर-स्थिर डेटा सदस्य नहीं है, तो उस ऑब्जेक्ट का कोई आधार वर्ग सबबॉज ([class.mem]) , या:
  • [...]

यदि दो ऑब्जेक्ट पॉइंटर-इंटरकनेक्टेबल होते हैं, तो उनका एक ही पता होता है, और एक पॉइंटर से दूसरे में reinterpret_cast माध्यम से पॉइंटर प्राप्त करना संभव है।

वह reinterpret_cast<Point*>(x) वैध है और एक पॉइंटर के साथ समाप्त होता है जो p को इंगित करता है। इसलिए, इसे सीधे संशोधित करना ठीक है। जैसा कि आप देख सकते हैं, मानक-लेआउट भाग और पहले गैर-स्थैतिक डेटा सदस्य भाग महत्वपूर्ण हैं।

यद्यपि यह प्रश्न में संकलक की तरह नहीं है, यदि आप एक पॉइंटर को पास करने के लिए और इसके बजाय px वापस करने के लिए अतिरिक्त लोड का अनुकूलन करते हैं।





offsetof