293 | | === Suppressing Warnings === |
294 | | ==== Supressing Warnings For A File By Making GCC See It As A System Header ==== |
295 | | For 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 |
296 | | |
297 | | #pragma GCC system_header // File considered a system header. |
298 | | |
299 | | Note 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. |
300 | | |
301 | | You 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 |
302 | | |
303 | | The -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. |
304 | | |
305 | | If 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: |
306 | | |
307 | | -Wsystem-headers |
308 | | |
309 | | Print 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. |
310 | | |
311 | | ==== Turning off warnings locally ==== |
312 | | So. 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.4''' 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. |
313 | | |
314 | | -fdiagnostics-show-option:: |
315 | | In GCC, for versions 4.2.4 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. |
316 | | #pragma GCC diagnostic push:: |
317 | | 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. |
318 | | #pragma GCC diagnostic pop:: |
319 | | 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. |
320 | | #pragma GCC diagnostic [warning|error|ignored] OPTION:: |
321 | | From GCC version 4.2.4 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" |
322 | | |
323 | | So starting from 4.2.4 but before 4.6, just put near the top of the file something like: |
324 | | |
325 | | #pragma GCC diagnostic ignored "-Wdeprecated-declarations |
326 | | |
327 | | For version 4.6 or later, you can insert this around the line that causes the spurious warning: |
328 | | |
329 | | #pragma GCC diagnostic push |
330 | | #pragma GCC diagnostic ignored "-Wdeprecated-declarations" |
331 | | |
332 | | // Next you would have your code that generates the spurious warning |
333 | | |
334 | | #pragma GCC diagnostic pop |
| 293 | |
683 | | |
684 | | ||?||class does not have a virtual destructor||Suppress or provide a virtual destructor.||??|| |
685 | | |
| 639 | === Suppressing Warnings in GCC === |
| 640 | With GCC there are a couple of options when you want to supress warnings. First, beginning with version 3.1, since GCC won't report warnings for files that GCC considers ''system'' files, you can make GCC consider the problematic files system files. This is heavy handed, makes it easy for problems to creep in unnoticed, but effective. Second, beginning with version 4.2, you can suppress a particular class of warning either for an entire file, or (beginning at version 4.6), for a section of a file. |
| 641 | ==== Supressing Warnings For A File By Making GCC See It As A System Header ==== |
| 642 | ===== Using a pragma to make GCC think a file or part of a file is a system header ===== |
| 643 | Beginning with GCC 3.1, for 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 |
| 644 | |
| 645 | #pragma GCC system_header // File considered a system header. |
| 646 | |
| 647 | 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. |
| 648 | ===== Using -i to make GCC think all files in a directory are system headers ===== |
| 649 | You 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 |
| 650 | |
| 651 | The -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. |
| 652 | |
| 653 | If 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 when you compile with: |
| 654 | |
| 655 | -Wsystem-headers |
| 656 | |
| 657 | This makes GCC print warning messages for constructs found in system header files that would normally not be seen. Using -Wall in conjunction with this option will not warn about unknown pragmas in system headers. For that, -Wunknown-pragmas must also be used. |
| 658 | |
| 659 | ==== Turning off warnings locally with gcc ==== |
| 660 | So. 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. |
| 661 | ===== Finding out what option controls the warning |
| 662 | -fdiagnostics-show-option:: |
| 663 | In GCC, for versions 4.2 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. The added text will look similar to [-Wsign-compare]. If you see this, that tells you that the -Wsign-compare command line option turns this warning on. |
| 664 | ===== Turning the warnings off and on |
| 665 | GCC provides the following pragmas to control warnings. |
| 666 | #pragma GCC diagnostic push:: |
| 667 | 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. The number of nested pushes is limited only by the size of memory and the size of an int index into the diagnostic information. |
| 668 | #pragma GCC diagnostic pop:: |
| 669 | 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. The number of pops is limited by memory and the size of an int index into the diagnostic information. At a pop information is moved from the table used by push into a history. An unbalanced pop, i.e. popping when nothing is on the stack is harmless and will simply reassert the user's command line diagnostic choices. |
| 670 | #pragma GCC diagnostic [warning|error|ignored] OPTION:: |
| 671 | From GCC version 4.2.4 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" |
| 672 | ====== version 4.2. You can turn them off but then what? |
| 673 | So starting from 4.2 but before 4.6, just put near the top of the file something like: |
| 674 | |
| 675 | #pragma GCC diagnostic ignored "-Wdeprecated-declarations |
| 676 | |
| 677 | to turn off warnings from that point forward in the file of the use of deprecated declarations. Problematically, you have no way of knowing what the user had this option set to. They might have already had the warnings turned on, they might have had them set to ignore, or they might have had them set to cause an error. At the end of the file, if you do nothing else, the diagnostic for deprecated declarations stays ignored for anything that includes your file. You can set them to ignored, error, or warning at the end of the file before exiting, but you don't know which to use. This is sure to cause angst. |
| 678 | ====== version 4.6 Now you can restore the user's flags |
| 679 | For version 4.6 or later, you can save the state of the user's diagnostic flags. You can insert this around the line that causes the spurious warning: |
| 680 | |
| 681 | #pragma GCC diagnostic push[[BR]] |
| 682 | #pragma GCC diagnostic ignored "-Wdeprecated-declarations" |
| 683 | |
| 684 | // Next you would have any amount of code for which you'd like to suppress that warning |
| 685 | |
| 686 | #pragma GCC diagnostic pop |
| 687 | |
| 688 | Of course this could cover everything from a line up to the whole file, and in between the push and the pop you could make multiple changes to each of multiple options. |
| 689 | |
| 690 | ====== A handy macro to help you do some of this |
| 691 | Jonathan Wakely came up with a nice macro set to control this and I'm sharing a slightly modified version of it with you. It defines: |
| 692 | GCC_DIAG_OFF(FLAG):: |
| 693 | For versions 4.2-4.5 will turn warnings off for a particular error if controllable via a -W command line flag. If -fdiagostics-show-option told you that the warning was controlled by [-Wsign-compare], then you could say GCC_DIAG_OFF(sign_compare). Beginning at version 4.6, it will push the current state of the diagnostic flags and then turning warning off. Prior to version 4.2 it has no effect. |
| 694 | GCC_DIAG_ON(FLAG):: |
| 695 | For versions 4.2-4.5 will arbitrarily turn warnings on. This may not be what the user wanted. Beginning at version 4.6 it will simply pop the saved diagnostic stack. Prior to version 4.2 it has no effect. |
| 696 | |
| 697 | Both of them should be used only at file scope for versions 4.2-4.5. Beginning at version 4.6 they can be used at any scope. If you want to turn multiple things from warning to error to ignored between the push and the pop then this will not be effective for you. |
| 698 | |
| 699 | It allows you to do things like: |
| 700 | {{{ |
| 701 | GCC_DIAG_OFF(sign-compare); |
| 702 | if(a < b){ |
| 703 | GCC_DIAG_ON(sign-compare); |
| 704 | }}} |
| 705 | to turn off warnings that you know are spurious. (Probably a cast of one to the other's type or changing the declaration of the type of one to the other's would be a better fix.) |
| 706 | |
| 707 | {{{ |
| 708 | #if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 402 |
| 709 | #define GCC_DIAG_STR(s) #s |
| 710 | #define GCC_DIAG_JOINSTR(x,y) GCC_DIAG_STR(x ## y) |
| 711 | # define GCC_DIAG_DO_PRAGMA(x) _Pragma (#x) |
| 712 | # define GCC_DIAG_PRAGMA(x) GCC_DIAG_DO_PRAGMA(GCC diagnostic x) |
| 713 | # if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406 |
| 714 | # define GCC_DIAG_OFF(x) GCC_DIAG_PRAGMA(push) \ |
| 715 | GCC_DIAG_PRAGMA(ignored GCC_DIAG_JOINSTR(-W,x)) |
| 716 | # define GCC_DIAG_ON(x) GCC_DIAG_PRAGMA(pop) |
| 717 | # else |
| 718 | # define GCC_DIAG_OFF(x) GCC_DIAG_PRAGMA(ignored GCC_DIAG_JOINSTR(-W,x)) |
| 719 | # define GCC_DIAG_ON(x) GCC_DIAG_PRAGMA(warning GCC_DIAG_JOINSTR(-W,x)) |
| 720 | # endif |
| 721 | #else |
| 722 | # define GCC_DIAG_OFF(x) |
| 723 | # define GCC_DIAG_ON(x) |
| 724 | #endif |
| 725 | }}} |
| 726 | |
| 727 | These are perhaps not the best choice of names for the macros since they risk future collision with GCC macros. In your domain you should probably prefix every instance of GCC_ with YOURDOMAIN_ to make YOURDOMAIN_GCC_, for example YOURDOMAIN_GCC_DIAG_OFF(x). |
| 728 | ---- |