{"id":3693,"date":"2010-12-14T09:56:00","date_gmt":"2010-12-14T09:56:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vcblog\/2010\/12\/14\/off-by-default-compiler-warnings-in-visual-c\/"},"modified":"2021-10-06T14:11:22","modified_gmt":"2021-10-06T14:11:22","slug":"off-by-default-compiler-warnings-in-visual-c","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/off-by-default-compiler-warnings-in-visual-c\/","title":{"rendered":"\u201cOff By Default\u201d Compiler Warnings in Visual C++"},"content":{"rendered":"<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2010\/12\/5850.image_thumb_2078AFA8.png\"><img decoding=\"async\" class=\"alignleft size-full wp-image-29343\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2010\/12\/5850.image_thumb_2078AFA8.png\" alt=\"Image 5850 image thumb 2078AFA8\" width=\"80\" height=\"104\" \/><\/a><\/p>\n<p><span style=\"font-size: small;\">Greetings! My name is Jon Sturgeon; I\u2019m a developer in the Forefront team here at Microsoft. I\u2019m happy to be able to contribute to the Visual C++ Team Blog as a \u201c<em>guest blogger<\/em>\u201d.<\/span><\/p>\n<p><span style=\"font-size: small;\">One of my passions when writing C++ code has always been to use as many techniques as possible to find bugs earlier and earlier in the development process; obviously the earlier that bugs are found the easier and cheaper they generally are to fix. And if they can be found and corrected before the code is even built, everybody wins.<\/span><\/p>\n<p><span style=\"font-size: small;\">\u00a0<\/span><\/p>\n<h2>Compiler Warning Levels<\/h2>\n<p><span style=\"font-size: small;\">I\u2019m assuming that everybody is familiar with the compiler warning level in the Visual C++ compiler. It is exposed through the \/W command-line switch and through the \u201cWarning Level\u201d item in the C\/C++ projects\u2019 properties page in the IDE:<\/span><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2010\/12\/8562.clip_image002_thumb_721F29FA.jpg\"><img decoding=\"async\" class=\"size-full wp-image-29344 aligncenter\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2010\/12\/8562.clip_image002_thumb_721F29FA.jpg\" alt=\"Image 8562 clip image002 thumb 721F29FA\" width=\"527\" height=\"86\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2010\/12\/8562.clip_image002_thumb_721F29FA.jpg 527w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2010\/12\/8562.clip_image002_thumb_721F29FA-300x49.jpg 300w\" sizes=\"(max-width: 527px) 100vw, 527px\" \/><\/a><\/p>\n<p><span style=\"font-size: small;\">The relevant part of the property page shown above is for a brand-new C++ project created in Visual Studio 2010. As you can see, the warning level is set to \/W3 by default. However, I recommend you compile all your code at warning level 4 instead, since the increase in warning \u201cnoise\u201d can be fairly minimal and there are some useful warnings that are only active with \/W4 enabled. It is best-practice in many teams to ensure that all code compiles cleanly with \/W4 enabled and the related option to treat all warnings as errors (\/WX) is often also specified to ensure that code cannot be submitted without first addressing all the warnings identified by the compiler.<\/span><\/p>\n<p><span style=\"font-size: small;\">\u00a0<\/span><\/p>\n<p>&nbsp;<\/p>\n<h2><span style=\"font-family: Courier New;\"><span style=\"font-weight: bold;\">\/Wall<\/span><\/span><\/h2>\n<p><span style=\"font-size: small;\">One warning option that isn\u2019t so well-known is <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/thxezb7y.aspx\">\/Wall<\/a>, shown in the IDE below:<\/span><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2010\/12\/3617.clip_image004_thumb_06A47979.jpg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-29342\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2010\/12\/3617.clip_image004_thumb_06A47979.jpg\" alt=\"Image 3617 clip image004 thumb 06A47979\" width=\"529\" height=\"174\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2010\/12\/3617.clip_image004_thumb_06A47979.jpg 529w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2010\/12\/3617.clip_image004_thumb_06A47979-300x99.jpg 300w\" sizes=\"(max-width: 529px) 100vw, 529px\" \/><\/a><\/p>\n<p><span style=\"font-size: small;\">This option (obviously) enables <i>all<\/i> warnings in the compiler. This of course leads to the question of what warnings are <i>not<\/i> enabled when \/W4 is specified? The answer can be found on <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/23k5d385%28v=VS.100%29.aspx\">this page<\/a> on MSDN which lists all the warnings that are \u201coff by default\u201d in the compiler. I\u2019m not going to walk through each and every warning in this list, but you can see that many of them are very trivial and \u201cnoisy\u201d warnings that you indeed are unlikely to want enabled on any realistic codebase. For instance, <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/96f5t7fy.aspx\">C4061<\/a> (\u201cenumerator in switch statement is not explicitly handled by a case label\u201d) is unlikely to identify any actual bugs and you\u2019d probably end up quickly disabling it if it was not off by default.<\/span><\/p>\n<p><span style=\"font-size: small;\">However, as you scan through the list, you can see that <i>some<\/i> of the warnings might identify potentially serious problems. A couple of my favorites relate to virtual functions: <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ay4h0tc9.aspx\">C4263<\/a> (member function does not override any base class virtual member function) and <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/tb55b5f4.aspx\">C4264<\/a> (no override available for virtual member function; function is hidden). In both of these cases, I want to know when my code triggers the warning, since there is quite likely to be an underlying bug that at the very least needs to be investigated.<\/span><\/p>\n<p><span style=\"font-size: small;\">\u00a0<\/span><\/p>\n<p>&nbsp;<\/p>\n<h2><span style=\"font-family: Courier New;\"><span style=\"font-weight: bold;\">\/Wall<\/span><\/span> in the Real World<\/h2>\n<p><span style=\"font-size: small;\">Since just enabling the \/Wall switch on a real-world codebase is going to be unrealistic due to all the noise from the trivial warnings, is there a way to gain the benefits of some of these more useful warnings without suffering the pain of the less useful ones? Yes there is, and here\u2019s the way I\u2019ve approached this in the past:<\/span><\/p>\n<ol>\n<li><span style=\"font-size: small;\">Create a header file that every project in your codebase can #include.<\/span><\/li>\n<li><span style=\"font-size: small;\">Force-include this header file in every translation unit in your codebase by using the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/8c5ztk84.aspx\">\/FI compiler option<\/a>.<\/span><\/li>\n<li><span style=\"font-size: small;\">Add <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/2c8f766e%28v=VS.100%29.aspx\">#pragma warning(disable:<i>&lt;warning number&gt;<\/i>)<\/a> lines to the header file to disable the individual warnings that produce nothing but noise for your codebase.<\/span><\/li>\n<li><span style=\"font-size: small;\">Turn on the \/Wall switch for your codebase.<\/span><\/li>\n<\/ol>\n<p><span style=\"font-size: small;\">Alternatively, you can use the same technique to selectively enable individual off-by-default compiler warnings and rebuild without adding the \/Wall switch. However, I prefer the first approach, since that way I\u2019m making explicit choices about which warnings I want disabled. Additionally, any future warnings that the compiler team adds in future releases will then be automatically enabled when the compiler is updated, at which time I can decide if it makes sense to keep them enabled.<\/span><\/p>\n<p><span style=\"font-size: small;\">\u00a0<\/span><\/p>\n<p>&nbsp;<\/p>\n<h2>Handling External Header Files<\/h2>\n<p><span style=\"font-size: x-small;\"><span style=\"font-size: small;\">One thing that you are likely to find when trying to build your codebase with many of these off-by-default warnings enabled is that some of the compiler\/SDK-supplied header files do not compile cleanly. I know that the Visual C++ &amp; Windows SDK teams are very good at ensuring all the standard headers will compile cleanly at warning level 4, but there are no such guarantees when enabling \/Wall. Because of this, if you want to gain the benefits of building with some of these warnings enabled, you\u2019ll need a solution to this problem. Unfortunately the best option I\u2019ve found so far is to wrap the offending header file an a header of your own which temporarily disables the offending warnings and arrange for your code to #include that instead. For instance, if your code uses ATL, you may need to use a header similar to this: <\/span>\n<\/span><\/p>\n<div id=\"scid:9D7513F9-C04C-4721-824A-2B34F0212519:714670ab-4df5-4c37-b288-b5f2ed8bfb25\" class=\"wlWriterEditableSmartContent\" style=\"margin: 0px; float: none; padding: 0px;\">\n<div style=\"padding-left: 30px;\"><!-- code highlighting produced by Actipro CodeHighlighter (freeware) http:\/\/www.CodeHighlighter.com\/ --><span style=\"font-family: 'courier new', courier;\"> <span style=\"color: #0000ff;\">#pragma<\/span><span style=\"color: #000000;\"> warning(push)<\/span> <span style=\"color: #0000ff;\">#pragma<\/span><span style=\"color: #000000;\"> warning(disable:4265)<\/span> <span style=\"color: #0000ff;\">#pragma<\/span><span style=\"color: #000000;\"> warning(disable:4625)<\/span> <span style=\"color: #0000ff;\">#pragma<\/span><span style=\"color: #000000;\"> warning(disable:4626)<\/span><span style=\"color: #0000ff;\"> #include <\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #000000;\">atlbase.h<\/span><span style=\"color: #000000;\">&gt;<\/span> <span style=\"color: #0000ff;\">#pragma<\/span><span style=\"color: #000000;\"> warning(pop)<\/span><\/span><\/div>\n<pre style=\"background-color: #ffff80; width: 595px; height: 110px; overflow: auto;\"><\/pre>\n<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http:\/\/dunnhq.com --><\/p>\n<\/div>\n<p><span style=\"font-size: small;\">This header file temporarily disables three of the off-by-default warnings that atlbase.h can generate, includes the header, then re-enables the warnings so that they are active again for your code. If you can arrange for this small header file to be found in your codebase\u2019s include path before any of the system headers, you can name it atlbase.h so you won\u2019t have to modify any of your actual source code\u2019s #include directives.<\/span><\/p>\n<p><span style=\"font-size: small;\">\u00a0<\/span><\/p>\n<p>&nbsp;<\/p>\n<h2>False Positives<\/h2>\n<p><span style=\"font-size: small;\">There are always false-positive scenarios with compiler warnings and the case is no different for the off-by-default warnings either. You\u2019ll have to use your judgment for each warning that you want to enable to see if the number of false positives that are generated in your codebase outweigh the potential for catching a real bug. One example where I think it can be worth suffering a few false-positives is <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/wzxffy8c.aspx\">C4265<\/a> &#8211; class has virtual functions, but destructor is not virtual. This warning, when enabled, is triggered by code like this:\n<\/span><\/p>\n<div id=\"scid:9D7513F9-C04C-4721-824A-2B34F0212519:38cc062d-e849-4f62-8dbe-d0abc093cc40\" class=\"wlWriterEditableSmartContent\" style=\"margin: 0px; float: none; padding: 0px;\">\n<p>&nbsp;<\/p>\n<div style=\"padding-left: 30px;\"><!-- code highlighting produced by Actipro CodeHighlighter (freeware) http:\/\/www.CodeHighlighter.com\/ --><span style=\"font-family: 'courier new', courier;\"> <span style=\"color: #0000ff;\">class<\/span><span style=\"color: #000000;\"> Animal { <\/span><span style=\"color: #0000ff;\">public<\/span><span style=\"color: #000000;\">: Animal(); <\/span><span style=\"color: #000000;\">~<\/span><span style=\"color: #000000;\">Animal(); <\/span><span style=\"color: #008000;\">\/\/<\/span><span style=\"color: #008000;\">not virtual<\/span> <span style=\"color: #0000ff;\">virtual<\/span> <span style=\"color: #0000ff;\">void<\/span><span style=\"color: #000000;\"> MakeNoise(); };<\/span><\/span><\/div>\n<pre style=\"background-color: #ffff80; width: 595px; height: 130px; overflow: auto;\"><\/pre>\n<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http:\/\/dunnhq.com --><\/p>\n<\/div>\n<p><span style=\"font-size: small;\">As you can see, the class has a virtual function, but the destructor is not declared <i>virtual<\/i>. This can be a real bug that can lead to memory leaks if objects that implement the Animal base class are expected to be created on the heap and later deleted through a pointer of Animal * type. Or this can be a false-positive (i.e. not a problem) if these objects have an alternative destruction mechanism, such as the virtual IUnknown::Release() method that all COM interfaces employ. Consequently, if you choose to build your code with this warning enabled, you\u2019ll have false-positive warnings in any code that implements COM interfaces. At this point you\u2019ll have to make a decision about whether the warning is likely to catch real bugs in your code; if you want to keep the warning enabled, you\u2019ll have to temporarily disable it around the false-positive locations, using the #pragma warning method shown in the atlbase.h example above.<\/span><\/p>\n<p><span style=\"font-size: small;\">\u00a0<\/span><\/p>\n<p>&nbsp;<\/p>\n<h2>Summary<\/h2>\n<p><span style=\"font-size: small;\">To sum up, here\u2019s my recommendations:<\/span><\/p>\n<ul>\n<li><span style=\"font-size: small;\">If you are not already building (cleanly) at warning level 4, start today!<\/span><\/li>\n<li><span style=\"font-size: small;\">Consider using the techniques above to enable some of the off-by-default compiler warnings<\/span><\/li>\n<\/ul>\n<p><span style=\"font-size: small;\">As a starting point, I\u2019d consider enabling these off-by-default warnings:<\/span><\/p>\n<ul>\n<li><span style=\"font-size: small;\"><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/w0eaaaf7%28v=VS.90%29.aspx\">C4191<\/a> &#8211; unsafe conversion from &#8216;type of expression&#8217; to &#8216;type required&#8217;<\/span><\/li>\n<li><span style=\"font-size: small;\"><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/3hca13eh.aspx\">C4242<\/a> &#8211; conversion from &#8216;type1&#8217; to &#8216;type2&#8217;, possible loss of data<\/span><\/li>\n<li><span style=\"font-size: small;\"><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ay4h0tc9.aspx\">C4263<\/a> &#8211; member function does not override any base class virtual member function<\/span><\/li>\n<li><span style=\"font-size: small;\"><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/tb55b5f4.aspx\">C4264<\/a> &#8211; no override available for virtual member function from base &#8216;class&#8217;; function is hidden<\/span><\/li>\n<li><span style=\"font-size: small;\"><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/wzxffy8c.aspx\">C4265<\/a> &#8211; class has virtual functions, but destructor is not virtual<\/span><\/li>\n<li><span style=\"font-size: small;\"><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/4b76ty10.aspx\">C4266<\/a> &#8211; no override available for virtual member function from base &#8216;type&#8217;; function is hidden<\/span><\/li>\n<li><span style=\"font-size: small;\"><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/c9ctb1z9.aspx\">C4302<\/a> &#8211; truncation from &#8216;type 1&#8217; to &#8216;type 2&#8217;<\/span><\/li>\n<li><span style=\"font-size: small;\"><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms235307.aspx\">C4826<\/a> &#8211; conversion from &#8216;type1&#8217; to &#8216;type2&#8217; is sign-extended. This may cause unexpected runtime behavior<\/span><\/li>\n<li><span style=\"font-size: small;\"><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/zayh85yw.aspx\">C4905<\/a> &#8211; wide string literal cast to &#8216;LPSTR&#8217;<\/span><\/li>\n<li><span style=\"font-size: small;\"><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ae10z5cb.aspx\">C4906<\/a> &#8211; string literal cast to &#8216;LPWSTR&#8217;<\/span><\/li>\n<li><span style=\"font-size: small;\"><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/cwck4ta9.aspx\">C4928<\/a> &#8211; illegal copy-initialization; more than one user-defined conversion has been implicitly applied<\/span><\/li>\n<\/ul>\n<p><span style=\"font-size: small;\">If you enable these warnings on your code and they help you to find real bugs, I\u2019d love to hear about them in the comments.<\/span><\/p>\n<p><span style=\"font-size: small;\">Finally, I\u2019d like to thank the Visual C++ team for allowing me to guest on their blog. Thanks!<\/span><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Greetings! My name is Jon Sturgeon; I\u2019m a developer in the Forefront team here at Microsoft. I\u2019m happy to be able to contribute to the Visual C++ Team Blog as a \u201cguest blogger\u201d. One of my passions when writing C++ code has always been to use as many techniques as possible to find bugs earlier [&hellip;]<\/p>\n","protected":false},"author":289,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[65],"class_list":["post-3693","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cplusplus","tag-compiler"],"acf":[],"blog_post_summary":"<p>Greetings! My name is Jon Sturgeon; I\u2019m a developer in the Forefront team here at Microsoft. I\u2019m happy to be able to contribute to the Visual C++ Team Blog as a \u201cguest blogger\u201d. One of my passions when writing C++ code has always been to use as many techniques as possible to find bugs earlier [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/3693","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/users\/289"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=3693"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/3693\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/35994"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=3693"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=3693"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=3693"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}