Changes between Version 9 and Version 10 of Guidelines/WarningsGuidelines


Ignore:
Timestamp:
Jan 10, 2011, 11:48:56 PM (12 years ago)
Author:
phorgan1
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Guidelines/WarningsGuidelines

    v9 v10  
    1313
    1414Suppressing a warning without altering code may simply mask a problem.
    15 The right approach is to determine why the warning occurs is to decide
     15The right approach is to determine why the warning occurs, to decide
    1616whether it is correct in the context, and if so, apply appropriate remediation.
    1717If the warning is not correct in the context, only then should it be suppressed.
     
    276276||C6385||invalid data: accessing <buffer name>, the readable size is <size1> bytes, but <size2> bytes may be read.||Code analyser False warning C6385 when a function result is used as an array index. See [https://connect.microsoft.com/VisualStudio/feedback/details/281033/] suggests this can be suppressed, unless a check on array bounds is wanted/necessary.||
    277277
    278 
    279 '''GCC'''
    280 
    281 With GCC, it is more difficult to deal with warnings because there is no way (yet) '''locally''' silence individual warnings.  It is considered important not to leave warnings switched off when meeting user code. This is an unresolved difficulty.
     278----
     279== Warnings for '''GCC''' ==
     280
     281With older versions of GCC, it is more difficult to deal with warnings because there is no way to '''locally''' silence individual warnings.  As of GCC version '''4.2''' they allowed suppression via pragma (actually you can choose whether a particular problem is a warning, error, or ignored).  Initially they didn't allow you to save the current state of affairs, so after suppressing the warning, you wouldn't know whether the user had it on, off, or causing an error.  You can imagine that this would be quite annoying for users who care about these things.  Also, the pragmas had to be at file scope rather than inside your code.  As of version '''4.6''' a pragma was added to push or to pop the state of diagnostics, and the pragmas now affect from the line they are specified in forward.  It is considered important not to leave warnings switched off when meeting user code. This is an unresolved difficulty when using GCC versions prior to '''4.6'''.
    282282
    283283On the other hand, the number of unhelpful warnings seems fewer.
     
    285285So more emphasis should be placed on fixing warnings, for example using static_cast, or providing missing items.
    286286
    287 For a particular file,
    288 
    289 #pragma GCC system_ // No warnings from all this file, considered a system header.
    290 
    291 or option --isystem
    292 
    293 The -isystem command line option adds its argument to the list of directories to search for headers, just like -I. Any headers found in that directory will be considered system headers.
     287=== Suppressing Warnings ===
     288==== Supressing Warnings For A File By Making GCC See It As A System Header ====
     289For a particular file, you can turn off all warnings including most warnings generated by the expansion of macros specified in a file by putting the following in a file
     290
     291#pragma GCC system_header // File considered a system header.
     292
     293Note that this works differently depending on the version of GCC prior to version 4.6 it needed to be put near the beginning of the file and before any code. All code in the file after the pragma is seen will be considered system code.  Since 4.6, it can be specified anywhere in the file, and code that precedes the pragma in the file will be unaffected.  The intent of declaring a file a system header, is for operating system specific code that can't be strictly conforming C or C++.  This should not be seen as a handy way of turning off bothersome warnings.  Many ('''most?''') warnings point to real issues and should be dealt with appropriately.
     294
     295You can also turn off warnings for all files in a directory, by putting the directory into the include search path with -i instead of -I
     296
     297The -idirectoryName command line option adds its argument to the list of directories to search for headers, just like -I. Any headers found in that directory will be considered system headers. It also has the side effect of changing the inclusion order, in that all files included from directories specified with -i are included '''after''' files included from directories specified via -I.  If the directory is specified with both -I and -i it is still only searched after normal includes as part of the system include directories.  This may be appropriate if you have to deal with other's spotty code that generates a lot of warnings that you can't fix.
     298
     299If you turn off warnings for files that are shared with your users, you need to be able to see the warnings yourself so that as new problems arise you will see them.  You can turn on warnings back on for system headers with:
    294300
    295301-Wsystem-headers
    296302
    297 is effective until the end of the file.
    298 
    299 Print warning messages for constructs found in system header files. Warnings from system headers are normally suppressed, on the assumption that they usually do not indicate real problems and would only make the compiler output harder to read. Using this command line option tells GCC to emit warnings from system headers as if they occurred in user code. However, note that using -Wall in conjunction with this option will not warn about unknown pragmas in system headers—for that, -Wunknown-pragmas must also be used.
    300 
    301 The GCC docs say: "Also, while it is syntactically valid to put these pragmas anywhere in your sources, the only supported location for them is before any data or functions are defined. Doing otherwise may result in unpredictable results depending on how the optimizer manages your sources."
    302 
    303 This might only mean you can't use them inside functions or class definitions, but it seems to imply that using them after a function definition leads to undefined behavior.  Thus, even if we knew what setting to turn the warning back to (perhaps the warning wasn't enabled in the first place!), we might not be able to turn them back on.
    304 
    305 <toolset>gcc:<cxxflags>-fdiagnostics-show-option # find out which options controls this warning (GCC >= 4.3)
    306 
    307 #if defined(__GNUC__) // GCC 4.3 and higher.
    308     #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
    309 #endif
    310 
    311 But that doesn't quite work, how do you know that the user wants -Wdeprecated-declarations to be set to "warning" after the include?
    312 Could be the user has disabled that one on the command line, in which case if we turn it back on, that's as annoying for the end user as warnings from Boost! There was a time when some MSVC std lib headers behaved like that, and believe me it was *seriously* annoying :-(
     303Print warning messages for constructs found in system header files that would normally not be seen. Warnings from system headers are normally suppressed, on the assumption that they usually do not indicate real problems and would only make the compiler output harder to read. Using this command line option tells GCC to emit warnings from system headers as if they occurred in user code. However, note that using -Wall in conjunction with this option will not warn about unknown pragmas in system headers—for that, -Wunknown-pragmas must also be used.
     304
     305==== Turning off warnings locally ====
     306So.  Suppose you are getting a warning and have checked the code and are '''sure''' that it's a spurious warning.  There's nothing wrong.  '''If''' the warning is controllable via a command line -W option, then you can (if you have GCC version '''4.2''' or newer) turn it off temporarily.  First you need to find out what the option might be, then if it exists turn it off via a pragma.  How you do this varies a bit with GCC version.
     307
     308 -fdiagnostics-show-option::
     309  In GCC, for versions 4.3 and higher, this option instructs the diagnostic machinery to add text to each diagnostic emitted, which indicates which command line option directly controls that diagnostic, when such an option is known to the diagnostic machinery.
     310 #pragma GCC diagnostic push::
     311  Available since GCC version 4.6, this pragma lets you remember diagnostic options in place at a particular time.  This pragma can occur on any line of a file.
     312 #pragma GCC diagnostic pop::
     313  Available since GCC version 4.6, this pragma lets you restore diagnostic options that were remembered by a diagnostic push. This pragma can occur on any line of a file.
     314 #pragma GCC diagnostic [warning|error|ignored] OPTION::
     315  After GCC version 4.1 and before GCC version 4.6 this could be specified at file scope outside of any functions, classes, unions, structs, or methods, to change the behavior when a particular class of error was seen.  For GCC version 4.6 and later, it can be put in any line of a file, and affects from that position forward.  For any supported version, it only works with warnings that have explicit -W arguments, use -fdiagnostic-show-option to find out which one to use.  An example: #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
     316
     317So prior to 4.6 just put near the top of the file something like:
     318
     319#pragma GCC diagnostic ignored "-Wdeprecated-declarations
     320
     321For version 4.6 or later, you can insert this around the line that causes the spurious warning:
     322
     323#pragma GCC diagnostic push
     324#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
     325
     326// Next you would have your code that generates the spurious warning
     327
     328#pragma GCC diagnostic pop
     329
     330=== Turning on Warnings ===
    313331
    314332-Wall
    315     This enables all the warnings about constructions that some users consider questionable, and that are easy to avoid (or modify to prevent the warning), even in conjunction with macros. This also enables some language-specific warnings described in C++ Dialect Options and Objective-C and Objective-C++ Dialect Options.
     333    This enables all the warnings about constructions that some users consider questionable, and that are easy to avoid (or modify to prevent the warning), even in conjunction with macros. This also enables some language-specific warnings described in C++ Dialect Options and Objective-C and Objective-C++ Dialect Options.  For specific information on any of these warnings please see http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
    316334
    317335    -Wall turns on the following warning flags:
     
    349367
    350368-Wextra
     369
    351370    This enables some extra warning flags that are not enabled by -Wall. (This option used to be called -W. The older name is still supported, but the newer name is more descriptive.)
    352371
     
    376395More information needed here!
    377396
    378 === Individual Warnings ===
     397=== Specific Warnings and Suggested Actions ===
    379398'''comparison between signed and unsigned integer expressions'''
    380399
     
    384403    Almost always points to a real issue. The ranges of these are obviously
    385404    different, for example signed char -128 - 127 and unsigned char 0 - 255 for
    386 
    387                     range               bit pattern
    388     signed char     -128 to 127     01111111 to 10000000
    389     unsigned char    0 to 255       00000000 to 11111111
    390 
    391     That means: signed char     unsigned char
    392       0 to 127      +               +
    393     128 to 255      -               +
    394 
     405   
     406    ||                ||= range =||=   bit pattern =||
     407    || signed char     || -128 to 127 || 01111111 to 10000000 ||
     408    || unsigned char  ||  0 to 255      || 00000000 to 11111111 ||
     409
     410    ||=That means:=||=signed char=||=unsigned char=||
     411    ||0 to 127|| + || + ||
     412    ||128 to 255|| \- || /+ ||
     413   
    395414    In the range from 128 to 255 a comparison from one to the other makes no
    396415    sense.  They can have the same bit pattern, yet test as not equal.  This