G ++ weird warning

While working on a toy project, I began to answer the SO question, which flooded me with a g ++ warning, which I do not understand.

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

Internet search I got the impression that this might be a g ++ error; is this really a mistake, and if so, is there a workaround? The full source code is too large to include, 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 a warning for each instance of the operator() template method, always on line 230.

EDIT

Apparently, the error is due to the use of map iterators, which can generate inline code, which the optimizer confuses. Rewriting the section, avoiding the use of iterators, I got shorter code, which is also easy to compile without warning.

 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; } 
+4
source share
3 answers

As far as I can tell, this comes from the code in map , and not from the 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 that deal with maps and are very similar to each other friend, that there are absolutely some cases when he warns incorrectly because he loses traces of dynamic types of objects. They also state that there are some cases where they are warmed up properly.

They also indicate that the warning is inserted in 4.5 until they can correctly implement it.

Finally, you tried to rewrite your method as follows to find out if this warning helps 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; } 
+4
source

I had seen this β€œmistake” before and decided that it was often pointless. I do not see anything wrong with your code. You can try your luck with the newer versions of GCC - it looks like I remember how it popped up somewhere around 4.3-4.4.

Edit: I said that this warning / error "often" is pointless. Generally not. "I absolutely do not advocate simply ignoring or disabling warnings just because they are annoying, but there is no obvious problem in this code and in some of my own code, despite the GCC complaint.

0
source
0
source

Source: https://habr.com/ru/post/1347436/


All Articles