Re: [boost] Supressing warnings

Paul Bristow wrote:
I have raised this issue before, inconclusively, but the question has now become more urgent now that I am packaging some math functions produced by John "Doing the Impossible" Maddock.
I am also interested in warning free (or at the very least, warning minimal) code.
IMO Boost-worthy code should be able to be compiled in strict mode, for MSVC level 4, without producing a blizzard of warnings.
Agreed.
Including a list of warnings that the authors of the library consider unhelpful, and in some cases, unfixable (specifically the warning "conditional expression is constant. ")
by using, for example
#ifdef _MSC_VER # pragma warning(disable: 4127) // conditional expression is constant. # pragma warning(disable: 4100) // unreferenced formal parameter. # pragma warning(disable: 4512) // assignment operator could not be generated. # pragma warning(disable: 4996) // 'std::char_traits<char>::copy' was declared deprecated. // needed ifndef _SCL_SECURE_NO_DEPRECATE or == 0 // #define _SCL_SECURE_NO_DEPRECATE = 1 // Avoid C4996 warning. // #define _SCL_SECURE_NO_DEPRECATE = 0 // get C4996 warning. #endif
is fine for that package, but also supresses these warnings for other code, which users rightly object to.
Indeed. What's even more annoying is that the Microsoft STL implementation produces warnings as well!
Pushing and poping warning levels is VERY tedious, and almost impractiable, and doesn't help non-MSVC platforms.
What is the best way to deal with this?
There is the possibility of doing: #ifndef BOOST_FOO #define BOOST_FOO #include <boost/something.hpp> #include <boost/disable_warnings.hpp> namespace boost { ... } #include <boost/enable_warnings.hpp> #endif I know that this isn't ideal, but would help support other platforms and be conststent - e.g. it would allow new warnings to be disabled if/when they arise. However, it will affect nearly all of Boost.
Is it to provide for MSVC includable files, say math_strict.hpp, test_strict.hpp, filesystem_strict.hpp ... containing the above (tailored for the library, if necessary)?
What about other platforms?
Metrowerks CodeWarrior is very annoying in strict (all warnings) mode and will complain about its standard library to the point where you just want to go back to the normal warning level! I am not sure about other compilers. NOTE: Instead of disabling the warnings, you can remove the warning by updating the code. For example: void foo( int bar ){} // unreferenced parameter void foo( int bar ){ bar; } // no warning! case 10: return 10; break; // unreachable code ^^^^ remove break; to prevent the warning bool foo(){ BOOL bar = TRUE; return bar; } // performance warning bool foo(){ BOOL bar = TRUE; return bar != FALSE; } // no warning int foo(){ long bar = 10l; return bar; } // conversion warning int foo(){ long bar = 10l; return int( bar ); } // conversion warning class foo { bar & m_bar; foo( bar & b ): m_bar( b ){} // disable the no default compiler assignment operator warning: inline foo & operator=( const foo & ); }; Doing these will remove a lot of the warnings in the code without requiring them being disabled. I am not sure about other compilers, but I assume that similar things will apply there. The deprecated warnings are a major pain. Consider: std::copy( first, last, dest ); This will not produce warnings with std::vector, etc. However, if you use char * it will produce: std::_Copy_impl was declared deprecated Huh! This is because std::copy will use memcpy for POD types and memcpy (and thus the internal implementation function) is deprecated! This is worse if std::copy is used in a template class/function you implement that could use POD types like the above, so is hard to write warning free. I also doubt disabling warnings will work here, because the warning will be generated at the point of instantiation! - Reece _________________________________________________________________ Try Live.com - your fast, personalized homepage with all the things you care about in one place. http://www.live.com/getstarted

In my opinion, a major problem with paying attention to warnings and changing the code in order to prevent warnings is, that in this way the code is not only written for a *special compiler*, but even **for a special compiler version**. I don't think that this is good practice. More and more people realise, that the code "should speak the truth", but code can be obfuscated by trying to prevent compiler warnings (for some special compiler, in some special version). Below I discuss some examples, where code is impaired by "preventing warnings". Having said this, in my experience gcc, version 4.1 or later, with "-ansi -pedantic -Wall" works quite well.
NOTE: Instead of disabling the warnings, you can remove the warning by updating the code. For example:
void foo( int bar ){} // unreferenced parameter void foo( int bar ){ bar; } // no warning!
this is FALSE: void foo(int){} is the right solution here, and follows the language. In "void foo( int bar ){ bar; }" only the special properties of build-in types makes it sementically equivalent, not so for other types; codes can get cluttered with these meaningless "helpful suggestions", less understood by the maintenance programmer, and when the type "int" gets upgraded to "Int" (big integers for example) then already something might happen (and other more extreme cases are conceivable).
bool foo(){ BOOL bar = TRUE; return bar; } // performance warning bool foo(){ BOOL bar = TRUE; return bar != FALSE; } // no warning
this is a perversion.
class foo { bar & m_bar; foo( bar & b ): m_bar( b ){}
// disable the no default compiler assignment operator warning: inline foo & operator=( const foo & ); };
again this is a perversion: the C++ should follow the LANGUAGE, and the special handling of the *special member function* is important part of C++. In the above example, first "inline" shouldn't be there, and then it's not about warnings, but about semantics: either we want the implicitely declared copy assignment operator, and then we *must not* add that line, or we don't want it, and then we *must* add the line --- there is no choice. Oliver

| -----Original Message----- | From: boost-bounces@lists.boost.org | [mailto:boost-bounces@lists.boost.org] On Behalf Of Oliver Kullmann | Sent: 27 June 2006 13:29 | To: boost@lists.boost.org | Subject: Re: [boost] Supressing warnings | | In my opinion, a major problem with paying | attention to warnings and changing the code in order | to prevent warnings is, that in this way the code | is not only written for a *special compiler*, but | even **for a special compiler version**. | I don't think that this is good practice. | | More and more people realise, that the code "should | speak the truth", but code can be obfuscated by trying | to prevent compiler warnings (for some special compiler, | in some special version). What about the MSVC warning 4127? silenced with # pragma warning(disable: 4127) // conditional expression is constant. No amount of recoding can help with this can this - a constant conditional expression is exactly what one was trying to achieve! What are you suggesting for this? Doing nothing is not an option, if you accept my premise that a -pedantic or MSVC level 4 compile without warnings is what we want. What mechanism for supressing it is best? | Having said this, in my experience gcc, version 4.1 or later, | with "-ansi -pedantic -Wall" works quite well. Does it produce a "conditional expression is constant" warning? (Or similar generally unhelpful messages). How can you stop it? Paul --- Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB +44 1539561830 & SMS, Mobile +44 7714 330204 & SMS pbristow@hetp.u-net.com

| More and more people realise, that the code "should | speak the truth", but code can be obfuscated by trying | to prevent compiler warnings (for some special compiler, | in some special version).
What about the MSVC warning 4127?
silenced with
# pragma warning(disable: 4127) // conditional expression is constant.
No amount of recoding can help with this can this - a constant conditional expression is exactly what one was trying to achieve!
What are you suggesting for this?
Doing nothing is not an option, if you accept my premise that a -pedantic or MSVC level 4 compile without warnings is what we want.
What mechanism for suppressing it is best?
| Having said this, in my experience gcc, version 4.1 or later, | with "-ansi -pedantic -Wall" works quite well.
Does it produce a "conditional expression is constant" warning? (Or similar generally unhelpful messages).
I just tried out several examples with gcc 4.1.0 and 4.1.1, using "-ansi -pedantic -Wall", and it didn't produce any warnings. Since error messages and warnings are not standardised, steps taken to silence one compiler(-version) might awaken another compiler(-version). (This was also mentioned in another reply.) Warnings should be there to help us, and not to bother us, or even dictate (bad) style; if the warning is *meaningful*, and we actually can *improve* the code, then fine, but otherwise the warning should be ignored My experience with gcc and "-ansi -pedantic -Wall" is actually, that except of one case (see below) every warning I encountered yet could be meaningfully handled, improving the code (conservatively, improving in at least one aspect, and not impairing in all others). Heavily using templates, this means a bit more work (for example partial specialisation to treat signed and unsigned integral types differently), but yet I found that it could be achieved without adding clutter, but by making the code more "precise". The only warnings ignored by me are "use of C99 long long integer constant" (coming for example from boost::integer_traits; this should sooner ore later disappear), and "the use of `tmpnam' is dangerous, better use `mkstemp'" (since tmpnam is part of the C standard; the warning has been appreciated, I looked into the issues, found the usage correct, and that's it). There won't be a general solution for this problem, because of the different compilers used (for example the above assumption that "MSVC level 4 compile without warnings is what we want" does not hold for me), but I would propose guidelines in the following direction: 1. Syntax errors and the like must be corrected (whether they are minor or not; see for example that semicolon-discussion some time ago). 2. Everybody should try to eliminate warnings by improving the code, but without compromising it --- since otherwise this might make it "better" for users of one compiler(-version), but worse for all other users. 3. For every compiler there is a list of warnings which may not be treated (while all others should be treated). With this list over time likely one sees that some compiler seem more reasonable (to the programmers in the boost context) than others. For gcc I would yet only have the C99 long long thing in the list (whatever people think of tmpnam, I don't think it's a problem for boost), while otherwise every boost library should treat all other errors. This third point is likely most important: Over time a standard should be developed, so that developers can see: Ah, it seems that warnings of this and that compiler should be treated, and it seems they can be treated reasonably, and perhaps there are also examples etc. And for other compiler it emerges that certain warnings cannot be handled or even shouldn't be handled. This all for the "core code". For the rest (to get rid off the remaining warnings) I think the special header-solution is appropriate: From the boost side everything was done (so well, nearly everything) to deliver good code, and the rest then is up to those users who use a special compiler and care about the warnings: Those users have a special interest, not shared by other users, and thus they must take some steps themselves (supported by Boost if possible). Oliver

On Tue, 27 Jun 2006 13:28:39 +0100, Oliver Kullmann <O.Kullmann@swansea.ac.uk> wrote:
In my opinion, a major problem with paying attention to warnings and changing the code in order to prevent warnings is, that in this way the code is not only written for a *special compiler*, but even **for a special compiler version**. I don't think that this is good practice.
I sympathize will all the points you make. Furthermore many VC level 4 warnings are quite excessive: for instance I get warnings if I do something like static_cast<smaller_int_type>(larger_int_type_expr); with the intent of truncating a value. Of course the static_cast is there to prevent a warning but VC8 tells me there's a loss of information and I should mask the source value. Example: unsigned int n = ... static_cast<unsigned char>( x & UCHAR_MAX ); It also specifies that there will be no performance loss in optimized builds, but of course that could not hold for other compilers. And there's always the risk that another compiler will yield something like: "useless masking used at line xyz" :) Something could be done with a macro in this case but... is it really worth? BTW, "C++ Coding Standards" by Sutter/Alexandrescu also suggests the "wrapping source file" (aka header) approach (on the user part though, not by boost directly). --Gennaro.

| -----Original Message----- | From: boost-bounces@lists.boost.org | [mailto:boost-bounces@lists.boost.org] On Behalf Of Oliver Kullmann | Sent: 27 June 2006 13:29 | To: boost@lists.boost.org | Subject: Re: [boost] Supressing warnings | | In my opinion, a major problem with paying | attention to warnings and changing the code in order | to prevent warnings is, that in this way the code | is not only written for a *special compiler*, but | even **for a special compiler version**. | I don't think that this is good practice. | | More and more people realise, that the code "should | speak the truth", but code can be obfuscated by trying | to prevent compiler warnings (for some special compiler, | in some special version). What about the MSVC warning 4127? silenced with # pragma warning(disable: 4127) // conditional expression is constant. No amount of recoding can help with this can this - a constant conditional expression is exactly what one was trying to achieve! What are you suggesting for this? Doing nothing is not an option, if you accept my premise that a -pedantic or MSVC level 4 compile without warnings is what we want. What mechanism for supressing it is best? | Having said this, in my experience gcc, version 4.1 or later, | with "-ansi -pedantic -Wall" works quite well. Does it produce a "conditional expression is constant" warning? (Or similar generally unhelpful messages). How can you stop it? Paul --- Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB +44 1539561830 & SMS, Mobile +44 7714 330204 & SMS pbristow@hetp.u-net.com

Reece Dunn wrote:
Paul Bristow wrote:
NOTE: Instead of disabling the warnings, you can remove the warning by updating the code. For example:
This is a better approach... warnings are there for a good reason, after all.
void foo( int bar ){} // unreferenced parameter void foo( int bar ){ bar; } // no warning!
Why is the parameter there in the first place? Either remove it if it is never used: void foo(void) { } or comment its name out but leave the type: void foo(int /* bar */) { } Either will avoid the compiler warning.
participants (5)
-
Gennaro Prota
-
Oliver Kullmann
-
Paul A Bristow
-
Paul Giaccone
-
Reece Dunn