简体   繁体   中英

g++ strange warning

Working on a toy project that I started to answer an SO question I'm getting flooded by a g++ warning that I don't understand.

format.hpp:230: warning: dereferencing pointer ‘<anonymous>’
does break strict-aliasing rules

searching on the internet I've got the impression that this could be a g++ bug; is it really a bug and if yes is there any workaround for it? The full source code is too big for inclusion but is available here . Here is the part where the warning is triggered...

template<typename T>
class ValueWrapper : public ValueWrapperBase
{
public:
    T x;
    ValueWrapper(const T& x) : x(x) {}
    virtual std::string toString(const Field& field) const
    {
        return Formatter<T>().toString(x, field);
    }
private:
    // Taboo
    ValueWrapper(const ValueWrapper&);
    ValueWrapper& operator=(const ValueWrapper&);
};

typedef std::map<std::string, ValueWrapperBase *> Env;

class Dict
{
private:
    Env env;

public:
    Dict() {}
    virtual ~Dict()
    {
        for (Env::iterator i=env.begin(), e=env.end(); i!=e; ++i)
            delete i->second;
    }

    template<typename T>
    Dict& operator()(const std::string& name, const T& value)
    {
        Env::iterator p = env.find(name);
        if (p == env.end())
        {
            env[name] = new ValueWrapper<T>(value);
        }
        else
        {
            ValueWrapperBase *vw = new ValueWrapper<T>(value);
            delete p->second;
            p->second = vw;
        }
        return *this;
    }

    const ValueWrapperBase& operator[](const std::string& name) const
    {
        Env::const_iterator p = env.find(name);
        if (p == env.end())
            throw std::runtime_error("Field not present");
        return *(p->second);
    }

private:
    // Taboo
    Dict(const Dict&);
    Dict& operator=(const Dict&);
};

Line 230 is p->second = vw; .

I get the warning for every instantiation of the template method operator() , always about line 230.

EDIT

Apparently the bug is about the use of map iterators that can generate inline code that confuses the optimizer. Rewriting a section avoiding using iterators I got shorter code that also compiles cleanly without warnings.

template<typename T>
Dict& operator()(const std::string& name, const T& value)
{
    ValueWrapperBase *vw = new ValueWrapper<T>(value);
    ValueWrapperBase *& p(env[name]);
    delete p;
    p = vw;
    return *this;
}

As far as I can tell this actually stems from code in map and not from your code itself.

According to http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42032 and http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43978 which both deal with maps and are very similar to each other, that there are absolutely some cases where it warns incorrectly because it loses track of the dynamic types of the objects. They equally state that there are some cases where it warms properly.

Also they indicate that the warning is shushed in 4.5 until they can implement it properly.

Finally, did you try rewriting your method as follows to see if it helps the warning in 4.3/4.4?

template<typename T>
Dict& operator()(const std::string& name, const T& value)
{
    ValueWrapperBase *vw = new ValueWrapper<T>(value);
    delete env[name];
    env[name] = new ValueWrapper<T>(value);

    return *this;
}

I've seen this "error" before and decided that it's often meaningless. I don't see anything wrong with your code. You might try your luck with newer versions of GCC--I seem to recall seeing this pop up somewhere around 4.3-4.4.

Edit: I said this warning/error is "often" meaningless. Not "usually." I absolutely do not advocate simply ignoring or disabling warnings just because they are annoying, but in this code, and in some of my own code, there is no apparent problem despite GCC's complaint.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM