Boost C++ Libraries: Ticket #4081: gcc warns about "comparision always true" for basic_binary_oarchive https://svn.boost.org/trac10/ticket/4081 <p> When upgrading to boost 1.42 I (and some other users too) ran into a problem with spurious warnings from (some versions of) gcc. </p> <p> Several of the save_override members of basic_binary_oarchive contain asserts to verify that the value about to be written is within a certain bound. Some of the test are in actual fact tautological, since they are of the form "x &lt;= numeric_limits&lt;T&gt;::const_max" with x being of type T. </p> <p> Ordinarily that wouldn't be a big deal, since the compiler can simply optimize away the test, and it provides at least some documentation of intent, and may provide some benefit against future changes elsewhere leading to unexpected problems. </p> <p> Unfortunately, for a substantial range of gcc versions, gcc issues a warning for such a tautological test, and worse yet, provides no mechanism for controlling the generation of these warnings. The specific warning is </p> <blockquote> <p> comparison is always true due to limited range of data type </p> </blockquote> <p> This is the subject of gcc bug 12963. The problematic version range appears to be from gcc 3.3.2 up to but not including gcc 4.3. From gcc 4.3 onward this is controlled by -W[no-]type-limits, which defaults to disabled and is enabled by -Wextra. </p> <p> Frankly I'm hard-pressed to think of a situation where I'd want to enable this warning, but unfortunately there's simply no way to disable it prior to gcc 4.3. </p> <p> I've locall worked around this gcc bug by patching the asserts in question to use boost.numeric.conversion to perform the range check, as it carefully optimizes out tests guaranteed to succeed, and so avoids triggering the warning in question. Specifically, my patch introduces the following helper function for use as the assertion test: </p> <blockquote> <p> template&lt;class T, class S&gt; bool save_override_check(S s) { </p> <blockquote> <p> return boost::numeric::cInRange </p> </blockquote> </blockquote> <h2 class="section" id="boost::numeric::converterTS::out_of_ranges">boost::numeric::converter&lt;T, S&gt;::out_of_range(s);</h2> <blockquote> <p> } </p> </blockquote> <p> which is used as </p> <blockquote> <p> assert(save_override_check&lt;boost::int_least16_t&gt;(t.t)); </p> </blockquote> <p> This was a sufficient solution for my local patch. However, it might not be desirable to add boost.numeric.conversion to the serialization library's dependencies just for this. A different approach would involve adding a value_type typedef to the classes defined by BOOST_STRONG_TYPEDEF, and change the tests to something like (with appropriate addition of "typename" and namespace qualifiers): </p> <blockquote> <p> template&lt;class T, class S&gt; bool save_override_check(S s) { </p> <blockquote> <p> return (numeric_limits&lt;S::value_type&gt;::const_max </p> <blockquote> <p> &lt;= numeric_limits&lt;T&gt;::const_max) </p> </blockquote> <table class="wiki"> <tr><td> (s.t &lt;= boost::numeric_limits&lt;T&gt;::const_max); </td></tr></table> </blockquote> <p> } </p> </blockquote> <p> Hopefully in this situation gcc would not warn about the now unreachable tautological comparision. I presume it would not complain about the comparison of two constants. </p> <p> The addition of a value_type typedef to the strong-typedef mechanism has some appeal independently of this, just for generally allowing some introspection on such types. </p> <p> My local patch didn't take the value_type approach because that would involve patching more files, and because I didn't have time to actually try it and perhaps discover that gcc was more stupid than I expected about this warning and still issued it in that situation. </p> <p> In followup discussion of this issue on the boost list, Robert Ramey had this to say: </p> <blockquote> <p> Well, this discussion makes me want to re-consider - at my leasure - what kind of checking - if any - should be done. It touches upon other issues as well, such as my imposed requirement that all archives should act identical. </p> </blockquote> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/4081 Trac 1.4.3 Robert Ramey Mon, 17 May 2010 20:35:18 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/4081#comment:1 https://svn.boost.org/trac10/ticket/4081#comment:1 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> I took these asserts out. </p> <p> Robert Ramey </p> Ticket