[cppx] /W4, no warnings, part II! (Disabling MSVC sillywarnings)

My original posting on how to avoid MSVC sillywarnings seemed to be quite popular. I’ve now added suppression of two more sillywarnings. The first of these is so braindead as to be almost unbelievable, it’s like it’s directly from the Department of Dumb: for the example below the compiler first (incorrectly) warns that type S “can never be instantiated”, and then it (correctly) goes on to instantiate it…

Example of MSVC sillywarning C4610 “can never be instantiated”:

struct S
{
    int const   n;
};

void use( S const& ) {}

int main()
{
    S   o   = {42};
    use( o );
}

This perfectly fine code compiles 100% cleanly with g++, while MSVC attempts to entertain you with not just one but three sillywarnings:

i_cant_well_ok.cpp(4) : warning C4510: 'S' : default constructor could not be generated
        i_cant_well_ok.cpp(2) : see declaration of 'S'
i_cant_well_ok.cpp(4) : warning C4512: 'S' : assignment operator could not be generated
        i_cant_well_ok.cpp(2) : see declaration of 'S'
i_cant_well_ok.cpp(4) : warning C4610: struct 'S' can never be instantiated - user defined constructor required

The other sillywarning I’ve now added suppression of is C4244, “conversion from ‘__w64 T‘ to ‘T‘, possible loss of data”. The __w64 keyword, now deprecated, was introduced to help identify 64-bit porting problems. When applied to a type it says that type might be 64-bit on a 64-bit platform, and so for purposes of warnings it should be treated as if it actually were 64-bit. This idea probably seemed to be a bright one at the time. But when an actual argument of a __w64 type selects a proper, correct overload with non-__w64 formal argument, e.g. as with the iostreams << operator, the result is an incorrect sillywarning, a very very annoying false positive!

Unfortunately there’s no way to detect in code whether a type has been ornamented with __w64, and so the only way to turn off these sillywarnings (without also turning off proper warnings) is to not use the /Wp64 “check for 64-bit portability issues” compiler option. Instead one should now use a 64-bit compiler to check for 64-bit portability issues. And happily the /Wp64 option is detectable, via the macro _Wp64 (I learned about that from Geoff Chappel’s web pages, and then, but not before, it was no problem finding it in Microsoft’s documentation).

File [progrock/cppx/compiler_specific/msvc/no_sillywarnings_please.h]:

// Copyright (c) Alf P. Steinbach, 2010.
// #include <progrock/cppx/compiler_specific/msvc/no_sillywarnings_please.h>

#ifndef PROGROCK_CPPX_COMPILERSPECIFIC_MSVC_NOSILLYWARNINGSPLEASE_H
#define PROGROCK_CPPX_COMPILERSPECIFIC_MSVC_NOSILLYWARNINGSPLEASE_H

#ifndef _MSC_VER
#   error This file is specific to the MSVC (Microsoft Visual C++) compiler.
#endif

#ifndef CPPX_ALLOW_WP64
#   // The /Wp64 option generates spurious warnings when a __w64 type argument selects
#   // a correct overload with non-__w64 formal argument type, i.e. for <<. In newer
#   // versions of MSVC this option is deprecated. It Really Annoyed a lot of people!
#   ifdef  _Wp64
#       error Do not use the /Wp64 option: use a 64-bit compiler to detect 64-bit portability issues.
#   endif
#endif

#pragma warning( disable: 4061 )    // enum value is not *explicitly* handled in switch
#pragma warning( disable: 4099 )    // first seen using 'struct' now seen using 'class'
#pragma warning( disable: 4127 )    // conditional expression is constant
#pragma warning( disable: 4217 )    // member template isn't copy constructor
#pragma warning( disable: 4250 )    // inherits (implements) some member via dominance
#pragma warning( disable: 4251 )    // needs to have dll-interface to be used by clients
#pragma warning( disable: 4275 )    // exported class derived from non-exported class
#pragma warning( disable: 4347 )    // "behavior change", function called instead of template
#pragma warning( disable: 4355 )    // "'this': used in member initializer list
#pragma warning( disable: 4505 )    // unreferenced function has been removed
#pragma warning( disable: 4510 )    // default constructor could not be generated
#pragma warning( disable: 4511 )    // copy constructor could not be generated
#pragma warning( disable: 4512 )    // assignment operator could not be generated
#pragma warning( disable: 4513 )    // destructor could not be generated
#pragma warning( disable: 4610 )    // can never be instantiated user defined constructor required
#pragma warning( disable: 4623 )    // default constructor could not be generated
#pragma warning( disable: 4624 )    // destructor could not be generated
#pragma warning( disable: 4625 )    // copy constructor could not be generated
#pragma warning( disable: 4626 )    // assignment operator could not be generated
#pragma warning( disable: 4640 )    // a local static object is not thread-safe
#pragma warning( disable: 4661 )    // a member of the template class is not defined.
#pragma warning( disable: 4670 )    // a base class of an exception class is inaccessible for catch
#pragma warning( disable: 4672 )    // a base class of an exception class is ambiguous for catch
#pragma warning( disable: 4673 )    // a base class of an exception class is inaccessible for catch
#pragma warning( disable: 4675 )    // resolved overload was found by argument-dependent lookup
#pragma warning( disable: 4702 )    // unreachable code, e.g. in <list> header.
#pragma warning( disable: 4710 )    // call was not inlined
#pragma warning( disable: 4711 )    // call was inlined
#pragma warning( disable: 4820 )    // some padding was added
#pragma warning( disable: 4917 )    // a GUID can only be associated with a class, interface or namespace

 // The following are real warnings but are generated by almost all MS headers, including
 // standard library headers, so it's impractical to leave them on.
#pragma  warning( disable: 4619 )   // there is no warning number 'XXXX'
#pragma  warning( disable: 4668 )   // XXX is not defined as a preprocessor macro

#endif

As mentioned also earlier a number of denizens of the Usenet group [comp.lang.c++] contributed to this list; thank you all!

And as also mentioned earlier, in addition to the above the general abstracting header includes a portable general warning suppression functionality header, which as of this writing still only defines …

In [progrock/cppx/devsupport/general_warnings_suppression.h]:

namespace progrock{ namespace cppx{ namespace devsupport {

    template< typename T >
    inline void suppressUnusedWarning( T const& ) {}

} } }  // namespace progrock::cppx::devsupport

Cheers, and … enjoy! 🙂

Advertisements

8 comments on “[cppx] /W4, no warnings, part II! (Disabling MSVC sillywarnings)

  1. I’ve been looking for a MSVC useless level 4 warning list for awhile. It is great to have a C++ guru to compile such a list.

    Thanks for the information!

    … Alan

  2. On the subject of undesired MSVC warnings, there’s one I disable
    unconditionally and globally since it was introduced:

    warning C4996: User:        did the standard change? :-O
                   Microsoft:   that's not really relevant... *but* you are giving
                                up the famous inventions that made us the company
                                which makes the less buffer overflow errors in the
                                world (as you all know)
    
                   (Microsoft reminds you to enable Automatic Updates for your OS)
    
    • I’ve now added C4996 (incorrectly warning that C standard library functions have been deprecated) – thanks! – and also C4428 (universal-character-name encountered in source), which both were introduced somewhere after MSVC 7.1.

      That’s the problem with this battle, that Microsoft keeps on adding new sillywarnings; they just never give up:

      Consequently I have placed a “latest” version of the file at a separate page, just follow the link. 🙂

  3. Hmm, perhaps you can tune the HTML a bit to have a “normal” background? 🙂

    PS:
    Please, s/the less/the least/, as well. While writing this, I was trying to implement std::lower_bound so that lower_bound( iter, iter, value ) would make at most log20 + 1 element comparisons, as required by the standard. Which explains the mental status.

    • I gather you’re talking about the background and formatting for <pre> tags. Sorry, I can’t do that centralized because it’s one of the ways WordPress makes money: you have to pay for the privilege of storing a CSS style sheet. But I think you can specify it in the comment as an inline style, like <pre style="background: green">:

      Warning C4996: 'printf': was declared deprecated
      

      Let’s see if that worked.

      Cheers,

      – Alf

          • Indeed! I hadn’t thought of this, because, knowing you, I’m in very relaxed mode here and in fact I was *asking* for a modification. 🙂

            (I might have been led astray but I seem to have seen something to tweak the CSS in the various WordPress pages. Perhaps it depends on what theme you choose? That is: it’s allowed with some themes and not allowed with others?)

            BTW, there should really be a comment preview: in the “logarithm distraction” I tried to be witty about an error in the standard, but “logarithm to base two of zero” became “log20”. Good Heavens :-O

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s