Работая над игрушечным проектом, на который я начал отвечать на вопрос SO, меня затопляет предупреждение g ++, которого я не понимаю.
format.hpp:230: warning: dereferencing pointer ‘<anonymous>’
does break strict-aliasing rules
поиск в интернете У меня сложилось впечатление, что этот может быть ошибкой g ++; действительно ли это ошибка, и если да, то есть ли обходной путь для этого? Полный исходный код слишком велик для включения, но доступно здесь . Вот та часть, где сработало предупреждение ...
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.
EDIT
Очевидно, ошибка связана с использованием итераторов карт, которые могут генерировать встроенный код, который сбивает с толку оптимизатор. Переписав раздел, избегая использования итераторов, я получил более короткий код, который также компилируется без предупреждений.
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;
}