c++ GCC '*(*(* शून्य*) और बी+4) के आसपास कैसे प्राप्त करें इस सुविधा की चेतावनी में अनसिनित किया जा सकता है, जबकि boost:: वैकल्पिक




g++ boost-optional (4)

मेरे पास निम्न के जैसा कोड है:

#include <boost/optional.hpp>

::boost::optional<int> getitem();

int go(int nr)
{
  boost::optional<int> a = getitem();
  boost::optional<int> b;

  if (nr > 0)
    b = nr;

  if (a != b)
    return 1;

  return 0;
}

निम्न आदेश का उपयोग करते हुए, बूस्ट 1.53 के साथ जीसीसी 4.7.2 के साथ संकलित करते समय:

जी ++ -क-ओ 2-वाल-डीएनडीईयूबीयूजी

निम्नलिखित चेतावनी जारी की गई है:

13: 3: चेतावनी: ' (शून्य ) और बी +4)' का उपयोग इस समारोह में प्रारंभ नहीं किया जा सकता है [-वायर-अनइनेरिज्ड]

जाहिर है, मूल समस्या जीसीसी के साथ है। जीसीसी बगजिला देखें क्या किसी को एक वैकल्पिक हल पता है?


जीसीसी में अनिर्धारित विश्लेषण के दो स्तर हैं:

  • -Wuninitialized : झंडे वेरिएबल्स जो निश्चित रूप से -Wuninitialized किए गए हैं
  • -Wmaybe-uninitialized : फ्लैग वेरिएबल्स जो संभावित रूप से उपयोग नहीं किए जा रहे हैं

जीसीसी (*) में, -Wall दोनों स्तरों पर मुड़ता है, हालांकि बाद के नकली चेतावनियां हैं क्योंकि विश्लेषण अपूर्ण है। नकली चेतावनियां एक प्लेग हैं, इसलिए उनसे बचने का सबसे सरल तरीका पारित करना है -Wno-maybe-uninitialized -Wall (बाद में -Wall )।

यदि आप अभी भी चेतावनियां चाहते हैं, लेकिन उनको विफल बनाने का कारण नहीं है (के माध्यम से- -Werror ) आप उन्हें सफेद सूची का उपयोग कर सकते हैं -Wno-error=maybe-uninitialized

(*) क्लैग सक्रिय नहीं होता -Wmaybe-uninitialized डिफ़ॉल्ट रूप से -Wmaybe-uninitialized ठीक से क्योंकि यह बहुत ही कमजोर है और झूठी सकारात्मक की एक अच्छी संख्या है; मैं चाहूंगा कि जीसीसी ने इस दिशानिर्देश का भी पालन किया।


मैंने पाया है कि बी का निर्माण निम्नलिखित (प्रभावी रूप से बराबर) कोड में बदल रहा है:

auto b = boost::make_optional(false,0);

चेतावनी को समाप्त करता है हालांकि, निम्नलिखित कोड (जो भी प्रभावी रूप से बराबर है):

boost::optional<int> b(false,0);

चेतावनी को समाप्त नहीं करता है यह अभी भी थोड़ा असंतोषजनक है ...


मेरे पास एक ऐसा प्रकार था जो आसानी से नहीं बनाया गया था ताकि बढ़ावा :: मेक-ऑप्शनल मार्ग नहीं जाना चाहता। किसी फ़ंक्शन से वापसी के उपयोग से ऑटो चर को इस समस्या के लिए मेरे पास मिल गया तो आप ऐसा कर सकते हैं:

boost::optional<Foo> Default()
{
    return boost::none;
}

auto var(Default());

यह एक पंक्ति लैम्ब्डा के रूप में भी काम करेगा ताकि आप यह कर सकें:

auto var([]()->boost::optional<Foo> { return boost::none; }());

कोड के इस टुकड़े के साथ एक ही मुद्दा था:

void MyClass::func( bool repaint, bool cond )
{
    boost::optional<int> old = m_sizeLimit; // m_sizeLimit is a boost::optional<int> class attribute

    if ( cond )
        m_sizeLimit = 60;
    else
        m_sizeLimit.reset();

    if ( repaint )
    {
        if ( old != m_sizeLimit ) // warning here
            doSomething();
    }
}

पॉल ओमटा के जवाब के साथ चेतावनी से छुटकारा नहीं पा सके, लिखने की कोशिश की:

boost::optional<int> old;
if ( m_sizeLimit )
    old = boost::make_optional<int>(true, m_sizeLimit.value());
else
    old = boost::make_optional<int>(false, 0);

... कोई सफलता नहीं के साथ

मेरे कोड से पूरी तरह से चेतावनी को अक्षम नहीं करना चाहता था, इसलिए मैंने एक वैकल्पिक समाधान पाया जिसमें मैं सुझाऊंगा: स्थानीय रूप से चेतावनी को अक्षम करें:

        #ifdef SDE_MOBILE
        #pragma GCC diagnostic push
        #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
        #endif

        if ( old != m_sizeLimit ) // warning here
            doSomething();

        #ifdef SDE_MOBILE
        #pragma GCC diagnostic pop
        #endif




boost-optional