g ++奇怪的警告

时间:2011-04-10 14:07:52

标签: c++ templates g++ warnings

在我开始回答一个问题的玩具项目上,我被一个我不理解的g ++警告所淹没。

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

在互联网上搜索我的印象是可能是一个g ++错误;它真的是一个错误,如果是的话有任何解决方法吗?完整的源代码太大而无法包含is available here。这是触发警告的部分......

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&);
};

第230行是p->second = vw;

我得到模板方法operator()的每个实例化的警告,总是关于第230行。

修改

显然,这个bug是关于使用可以生成混淆优化器的内联代码的map迭代器。重写一个避免使用迭代器的部分我得到了更短的代码,它也可以在没有警告的情况下干净地编译。

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;
}

3 个答案:

答案 0 :(得分:4)

据我所知,这实际上源于map中的代码,而不是来自代码本身。

根据http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42032http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43978两者都处理地图并且彼此非常相似,绝对有些情况下它会发出不正确的警告,因为它会丢失对象的动态类型。他们同样声明在某些情况下它会正常变暖。

此外,他们还表示警告会在4.5中被发送,直到他们能够正确实施。

最后,您是否尝试按如下方式重写您的方法以查看它是否有助于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;
}

答案 1 :(得分:0)

我之前看过这个“错误”,并认为它通常毫无意义。我没看到你的代码有什么问题。你可以尝试使用更新版本的GCC - 我似乎记得在4.3-4.4左右看到这个弹出窗口。

编辑:我说这个警告/错误“经常”毫无意义。不是“通常”。我绝对不提倡仅仅因为它们很烦人而忽略或禁用警告,但在这段代码中,以及在我自己的一些代码中,尽管有GCC的投诉,但没有明显的问题。

答案 2 :(得分:0)