c++ - "डेरेफेरिंग टाइप-पाइंट पॉइंटर सख्त-अलियासिंग नियम तोड़ देगा" चेतावनी




warnings strict-aliasing (4)

आप अपना डेटा डालने के लिए निम्न कोड का उपयोग कर सकते हैं:

template<typename T, typename F>
struct alias_cast_t
{
    union
    {
        F raw;
        T data;
    };
};

template<typename T, typename F>
T alias_cast(F raw_data)
{
    alias_cast_t<T, F> ac;
    ac.raw = raw_data;
    return ac.data;
}

उदाहरण का उपयोग:

unsigned int data = alias_cast<unsigned int>(raw_ptr);

मैं एक कोड का उपयोग करता हूं जहां मैंने एक enum * int * डाला। कुछ इस तरह:

enum foo { ... }
...
foo foobar;
int *pi = reinterpret_cast<int*>(&foobar);

कोड संकलित करते समय (g ++ 4.1.2), मुझे निम्नलिखित चेतावनी संदेश मिलता है:

dereferencing type-punned pointer will break strict-aliasing rules

मैंने इस संदेश को देखा, और पाया कि यह केवल तब होता है जब सख्त अलियासिंग अनुकूलन होता है। मेरे पास निम्नलिखित प्रश्न हैं:

  • यदि मैं इस चेतावनी के साथ कोड छोड़ता हूं, तो क्या यह संभावित गलत कोड उत्पन्न करेगा?
  • क्या इस समस्या के आसपास काम करने का कोई तरीका है?
  • यदि ऐसा नहीं है, तो क्या स्रोत फ़ाइल के अंदर से सख्त एलियासिंग बंद करना संभव है (क्योंकि मैं इसे सभी स्रोत फ़ाइलों के लिए बंद नहीं करना चाहता और मैं इस स्रोत फ़ाइल के लिए एक अलग मेकफाइल नियम नहीं बनाना चाहता। )?

और हां, मुझे वास्तव में इस तरह के अलियासिंग की जरूरत है।


क्या आपने इस उत्तर पर ध्यान दिया है ?

सख्त अलियासिंग नियम इस सेटअप को अवैध बनाता है, दो असंबंधित प्रकार एक ही मेमोरी को इंगित नहीं कर सकते हैं। केवल चार * को यह विशेषाधिकार प्राप्त है । दुर्भाग्य से आप अभी भी इस तरह से कोड कर सकते हैं, शायद कुछ चेतावनी प्राप्त करें, लेकिन क्या यह ठीक संकलन है।


लेकिन आप ऐसा क्यों कर रहे हैं? अगर आकार (फू)! = आकार (इंट)। सिर्फ इसलिए कि एक एनम एक पूर्णांक की तरह है इसका मतलब यह नहीं है कि यह एक के रूप में संग्रहीत है।

तो हाँ, यह "संभावित" गलत कोड उत्पन्न कर सकता है।


सख्त अलियासिंग एक संकलक विकल्प है, इसलिए आपको इसे मेकफाइल से बंद करने की आवश्यकता है।

और हाँ, यह गलत कोड उत्पन्न कर सकता है। कंपाइलर प्रभावी रूप से यह मान लेगा कि foobar और pi एक साथ बंधे हुए नहीं हैं, और यह मान लेंगे कि अगर foobar नहीं बदले तो *pi बदल जाएगा।

जैसा कि पहले ही उल्लेख किया गया है, इसके बजाय static_cast (और कोई संकेत नहीं) का उपयोग करें।





strict-aliasing