[wave][function] Suppressing gcc-4.4.1 warnings

Looks like the new type-punning warnings from gcc-4.4.1 are false positives (but I'd like someone else to confirm that!). The fixes below illustrate how to suppress them simply by declaring a temporary variable. HTH, John. Index: boost/wave/util/flex_string.hpp =================================================================== --- boost/wave/util/flex_string.hpp (revision 57230) +++ boost/wave/util/flex_string.hpp (working copy) @@ -1211,7 +1211,10 @@ }; Storage& Data() const - { return *reinterpret_cast<Storage*>(buf_); } + { + Storage* p = reinterpret_cast<Storage*>(buf_); + return *p; + } RefCountType GetRefs() const { Index: boost/function/function_base.hpp =================================================================== --- boost/function/function_base.hpp (revision 57230) +++ boost/function/function_base.hpp (working copy) @@ -316,11 +316,13 @@ new ((void*)&out_buffer.data) functor_type(*in_functor); if (op == move_functor_tag) { - reinterpret_cast<functor_type*>(&in_buffer.data)->~Functor(); + functor_type* f = reinterpret_cast<functor_type*>(&in_buffer.data); + f->~Functor(); } } else if (op == destroy_functor_tag) { // Some compilers (Borland, vc6, ...) are unhappy with ~functor_type. - reinterpret_cast<functor_type*>(&out_buffer.data)->~Functor(); + functor_type* f = reinterpret_cast<functor_type*>(&out_buffer.data); + f->~Functor(); } else if (op == check_functor_type_tag) { const BOOST_FUNCTION_STD_NS::type_info& check_type = *out_buffer.type.type;

Looks like the new type-punning warnings from gcc-4.4.1 are false positives (but I'd like someone else to confirm that!).
The fixes below illustrate how to suppress them simply by declaring a temporary variable.
Thanks John, I figured that much (and all related warnings caused by Wave are gone, btw - only some coming from optional are still there). Regards Hartmut ------------------- Meet me at BoostCon http://boostcon.com

On Thu, Nov 5, 2009 at 7:17 AM, John Maddock <john@johnmaddock.co.uk> wrote:
Looks like the new type-punning warnings from gcc-4.4.1 are false positives (but I'd like someone else to confirm that!).
The fixes below illustrate how to suppress them simply by declaring a temporary variable.
HTH, John.
Index: boost/wave/util/flex_string.hpp =================================================================== --- boost/wave/util/flex_string.hpp (revision 57230) +++ boost/wave/util/flex_string.hpp (working copy) @@ -1211,7 +1211,10 @@ };
Storage& Data() const - { return *reinterpret_cast<Storage*>(buf_); } + { + Storage* p = reinterpret_cast<Storage*>(buf_); + return *p; + }
What a terrible warning. You'd think reinterpret_cast<> would be enough to tell the compiler to back off. And the 'fixed' code is no better or worse. (I actually find the original version more understandable - ie closer to the intent of the code.) And what if the next version of the compiler recognizes the fixed code as bad as well? At some point will it be 'you just can't do that'? (P.S. can't you reinterpret_cast references as well? ie reinterpret_cast<Storage &> ?) Sigh. Anyhow, what I originally wanted to say about this whole warnings business is "A journey of a thousand miles begins with a single step." (Confucius) ie we just need to start fixing warnings and whittle it down one at a time. And lastly, isn't gcc open source? Could someone add #pragma push/pop/ignore etc or are they philosophically against that? Seems hard/impossible to tweak warnings in gcc. Tony

on Thu Nov 05 2009, Gottlob Frege <gottlobfrege-AT-gmail.com> wrote:
You'd think reinterpret_cast<> would be enough to tell the compiler to back off. And the 'fixed' code is no better or worse. (I actually find the original version more understandable - ie closer to the intent of the code.) And what if the next version of the compiler recognizes the fixed code as bad as well? At some point will it be 'you just can't do that'? (P.S. can't you reinterpret_cast references as well? ie reinterpret_cast<Storage &> ?)
Why is any Boost code using reinterpret_cast? There's very little you can do portably with reinterpret_cast, and IIRC, what little you *can* do portably can also be done with static_cast. -- Dave Abrahams Meet me at BoostCon: http://www.boostcon.com BoostPro Computing http://www.boostpro.com

On Fri, Nov 6, 2009 at 7:55 PM, David Abrahams <dave@boostpro.com> wrote:
Why is any Boost code using reinterpret_cast? There's very little you can do portably with reinterpret_cast, and IIRC, what little you *can* do portably can also be done with static_cast.
Didn't check, but I think this case (flex_string) was probably doing some kind of small buffer optimization. Regardless, consider something like boost optional. Doesn't it hold a non-allocated buffer for the optional T? The type of the buffer is probably char []. I haven't tried it, but can you static_cast that to T? Via an intermediate cast to void * or something? (And do we know if static_cast would solve the original warnings? This is orthogonal to whether we should ever use reinterpret_cast, of course.) P.S. I agree that its use should definitely be very limited. Tony

on Fri Nov 06 2009, Gottlob Frege <gottlobfrege-AT-gmail.com> wrote:
Didn't check, but I think this case (flex_string) was probably doing some kind of small buffer optimization. Regardless, consider something like boost optional. Doesn't it hold a non-allocated buffer for the optional T? The type of the buffer is probably char []. I haven't tried it, but can you static_cast that to T? Via an intermediate cast to void * or something?
Yes, exactly that way; and it's well-defined.
(And do we know if static_cast would solve the original warnings? This is orthogonal to whether we should ever use reinterpret_cast, of course.)
I have no idea; that's compiler specific, but I've never seen a warning about a static_cast. -- Dave Abrahams Meet me at BoostCon: http://www.boostcon.com BoostPro Computing http://www.boostpro.com

On Fri, Nov 6, 2009 at 11:51 PM, David Abrahams <dave@boostpro.com> wrote:
on Fri Nov 06 2009, Gottlob Frege <gottlobfrege-AT-gmail.com> wrote:
Didn't check, but I think this case (flex_string) was probably doing some kind of small buffer optimization. Regardless, consider something like boost optional. Doesn't it hold a non-allocated buffer for the optional T? The type of the buffer is probably char []. I haven't tried it, but can you static_cast that to T? Via an intermediate cast to void * or something?
Yes, exactly that way; and it's well-defined.
1. Is static_cast<X *>(static_cast<void *>(&z)) really any better than reinterpret_cast<X *>(&z) ? In what way(s)? ie to me, they can both cause equal amounts of trouble. 2. What is left for reinterpret_cast to do? casting to/from ints to pointers, etc? (useful in lockfree programming, etc). Which would be better accomplished with unions I suppose. In other words, What can reinterpret_cast do that other methods can't, and a) if any unique abilities exist, are they always evil? or b) if no unique abilities exist, are the other methods equally evil? Or by selecting particular methods (other than reinterpret) for each use case are we just being more careful and more specific in our intent? Tony

Gottlob Frege wrote:
2. What is left for reinterpret_cast to do? casting to/from ints to pointers, etc? (useful in lockfree programming, etc). Which would be better accomplished with unions I suppose.
Casting from pointer-to-function to pointer-to-object types (e.g., void*) is conditionally-supported for reinterpret_cast, and there's a guarantee that if both directions are supported, you can call through the pointer after casting it back to its original type. static_cast can't do this. (There's also the question of why you'd do this at all -- if you really need a typeless function pointer, you can cast to void(*)() with static_cast.) --Jeffrey

Jeffrey Bosboom wrote:
Gottlob Frege wrote:
2. What is left for reinterpret_cast to do? casting to/from ints to pointers, etc? (useful in lockfree programming, etc). Which would be better accomplished with unions I suppose.
Casting from pointer-to-function to pointer-to-object types (e.g., void*) is conditionally-supported for reinterpret_cast, and there's a guarantee that if both directions are supported, you can call through the pointer after casting it back to its original type. static_cast can't do this. (There's also the question of why you'd do this at all --
To cast the return value of dlsym to the proper type.

Gottlob Frege wrote:
1. Is static_cast<X *>(static_cast<void *>(&z)) really any better than reinterpret_cast<X *>(&z) ?
No.
2. What is left for reinterpret_cast to do? casting to/from ints to pointers, etc? (useful in lockfree programming, etc).
Yes.
Which would be better accomplished with unions I suppose.
No. :-)
participants (6)
-
David Abrahams
-
Gottlob Frege
-
Hartmut Kaiser
-
Jeffrey Bosboom
-
John Maddock
-
Peter Dimov