Changes between Version 27 and Version 28 of Guidelines/WarningsGuidelines


Ignore:
Timestamp:
Dec 6, 2012, 3:17:40 PM (6 years ago)
Author:
Paul A. Bristow
Comment:

Added macro specific to Clang and examples.

Legend:

Unmodified
Added
Removed
Modified
  • Guidelines/WarningsGuidelines

    v27 v28  
    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.
     18
     19To suppress warnings on all platforms is tedious hard work becuase every compiler provides different warnings and different ways of supressing warnings.
     20[http://sourceforge.net/p/predef/wiki/Compilers/]
     21gives macros provided by compilers that may help in pre-processing to chose the right method.
     22
     23But it is usually less trouble to eliminate the problem by better coding.
    1824
    1925Because developers don't have the same knowledge, even among Boost
     
    48545  To improve compliance with the C++ Standard.
    4955
    50 6  To permit users to set high warning levels when using Boost libraries without being overwhelmed with a barrage of library warnings.
     566  To permit users using Boost libraries to set high warning levels for their code without being overwhelmed with a barrage of library warnings.
    5157
    52587  To document that warnings have been considered by the library author or maintainer
     
    778784to 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.
    779785====== version 4.6 Now you can restore the user's flags
    780 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:
     786For version 4.6 or later, you can save the state of the user's diagnostic flags.
     787
     788See [http://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html]
     789
     790  You can insert this around the line that causes the spurious warning:
    781791{{{
    782792#pragma GCC diagnostic push[[BR]]
     
    790800Of 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.
    791801
    792 ====== A handy macro to help you do some of this
     802== ====== ==
     803 A handy macro to help you do some of this
     804
    793805Jonathan 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:
    794806 GCC_DIAG_OFF(FLAG)::
     
    866878
    867879-Wall turns on the following warning flags:
    868 
    869           -Waddress   
    870           -Warray-bounds (only with -O2) 
    871           -Wc++11-compat 
    872           -Wchar-subscripts 
    873           -Wenum-compare (in C/ObjC; this is on by default in C++)
    874           -Wimplicit-int (C and Objective-C only)
    875           -Wimplicit-function-declaration (C and Objective-C only)
    876           -Wcomment 
    877           -Wformat   
    878           -Wmain (only for C/ObjC and unless -ffreestanding) 
    879           -Wmaybe-uninitialized
    880           -Wmissing-braces (only for C/ObjC)
    881           -Wnonnull 
    882           -Wparentheses 
    883           -Wpointer-sign 
    884           -Wreorder   
    885           -Wreturn-type 
    886           -Wsequence-point 
    887           -Wsign-compare (only in C++) 
    888           -Wstrict-aliasing 
    889           -Wstrict-overflow=1 
    890           -Wswitch 
    891           -Wtrigraphs 
    892           -Wuninitialized 
    893           -Wunknown-pragmas 
    894           -Wunused-function 
    895           -Wunused-label     
    896           -Wunused-value     
    897           -Wunused-variable 
    898           -Wvolatile-register-var
    899 
     880{{{
     881  -Waddress   
     882  -Warray-bounds (only with -O2) 
     883  -Wc++11-compat 
     884  -Wchar-subscripts 
     885  -Wenum-compare (in C/ObjC; this is on by default in C++)
     886  -Wimplicit-int (C and Objective-C only)
     887  -Wimplicit-function-declaration (C and Objective-C only)
     888  -Wcomment 
     889  -Wformat   
     890  -Wmain (only for C/ObjC and unless -ffreestanding) 
     891  -Wmaybe-uninitialized
     892  -Wmissing-braces (only for C/ObjC)
     893  -Wnonnull 
     894  -Wparentheses 
     895  -Wpointer-sign 
     896  -Wreorder   
     897  -Wreturn-type 
     898  -Wsequence-point 
     899  -Wsign-compare (only in C++) 
     900  -Wstrict-aliasing 
     901  -Wstrict-overflow=1 
     902  -Wswitch 
     903  -Wtrigraphs 
     904  -Wuninitialized 
     905  -Wunknown-pragmas 
     906  -Wunused-function 
     907  -Wunused-label     
     908  -Wunused-value     
     909  -Wunused-variable 
     910  -Wvolatile-register-var
     911}}}
    900912-Wextra
    901913    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.)
    902 
    903               -Wclobbered 
    904               -Wempty-body 
    905               -Wignored-qualifiers
    906               -Wmissing-field-initializers 
    907               -Wmissing-parameter-type (C only) 
    908               -Wold-style-declaration (C only) 
    909               -Woverride-init 
    910               -Wsign-compare 
    911               -Wtype-limits 
    912               -Wuninitialized 
    913               -Wunused-parameter (only with -Wunused or -Wall)
    914               -Wunused-but-set-parameter (only with -Wunused or -Wall) 
    915    
     914{{{
     915  -Wclobbered 
     916  -Wempty-body 
     917  -Wignored-qualifiers
     918  -Wmissing-field-initializers 
     919  -Wmissing-parameter-type (C only) 
     920  -Wold-style-declaration (C only) 
     921  -Wsign-compare 
     922  -Wtype-limits 
     923  -Wuninitialized 
     924  -Wunused-parameter (only with -Wunused or -Wall)
     925  -Wunused-but-set-parameter (only with -Wunused or -Wall) 
     926 }}} 
    916927The option -Wextra also prints warning messages for the following cases:
    917 
    918         A pointer is compared against integer zero with `<', `<=', `>', or `>='.
    919         (C++ only) An enumerator and a non-enumerator both appear in a conditional expression.
    920         (C++ only) Ambiguous virtual bases.
    921         (C++ only) Subscripting an array that has been declared `register'.
    922         (C++ only) Taking the address of a variable that has been declared `register'.
    923         (C++ only) A base class is not initialized in a derived class's copy constructor.
    924 
     928{{{
     929  A pointer is compared against integer zero with `<', `<=', `>', or `>='.
     930  (C++ only) An enumerator and a non-enumerator both appear in a conditional expression.
     931  (C++ only) Ambiguous virtual bases.
     932  (C++ only) Subscripting an array that has been declared `register'.
     933  (C++ only) Taking the address of a variable that has been declared `register'.
     934  (C++ only) A base class is not initialized in a derived class's copy constructor.
     935}}}
    925936However, it may still be necessary to suppress those that are not providing any useful guidance and cannot be reasonably eliminated.
    926937
     
    931942To ignore via a command line, to an option like "-Wunused-variable" add a preceeding "no-" thus: "-Wno-unused-variable".
    932943
    933 In a jamfile, add
    934 {{{
    935 <cxxflags>-Wno-unused-variable
     944In a jamfile, add, for example:
     945{{{
     946<toolset=clang><cxxflags>-Wno-unused-variable
    936947<cxxflags>-Wno-maybe-uninitialized
    937948...
     
    955966}}}
    956967
    957 
    958 More info needed on Clang.
     968But this is not portable and will produce 'unrecognized pragmas' on other platforms.
     969
     970Macros that allow this to be done without causing complaint from other compilers is
     971{{{
     972
     973#ifdef __clang__
     974#  define CLANG_DIAG_STR(s) # s
     975// stringize s to "no-unused-variable"
     976#  define CLANG_DIAG_JOINSTR(x,y) CLANG_DIAG_STR(x ## y)
     977//  join -W with no-unused-variable to "-Wno-unused-variable"
     978#  define CLANG_DIAG_DO_PRAGMA(x) _Pragma (#x)
     979// _Pragma is unary operator  #pragma ("")
     980#  define CLANG_DIAG_PRAGMA(x) CLANG_DIAG_DO_PRAGMA(clang diagnostic x)
     981#    define CLANG_DIAG_OFF(x) CLANG_DIAG_PRAGMA(push) \
     982          CLANG_DIAG_PRAGMA(ignored CLANG_DIAG_JOINSTR(-W,x))
     983// For example: #pragma clang diagnostic ignored "-Wno-unused-variable"
     984#   define CLANG_DIAG_ON(x) CLANG_DIAG_PRAGMA(pop)
     985// For example: #pragma clang diagnostic warning "-Wno-unused-variable"
     986#else // Ensure these macros so nothing for other compilers.
     987#  define CLANG_DIAG_OFF(x)
     988#  define CLANG_DIAG_ON(x)
     989#  define CLANG_DIAG_PRAGMA(x)
     990#endif
     991
     992/* Usage:
     993  CLANG_DIAG_OFF(unused-variable)
     994  CLANG_DIAG_OFF(unused-parameter)
     995  CLANG_DIAG_OFF(uninitialized)
     996 */
     997}}}
     998
     999
     1000{{{
     1001#include <iostream>
     1002#include <boost/assert.hpp>
     1003
     1004int main()
     1005{
     1006  #ifdef __clang__
     1007  std::cout << "Clang "<< __clang_major__ << '.' << __clang_minor__<< '.' << __clang_patchlevel__ << std::endl;
     1008  #endif
     1009
     1010
     1011// Clang method of saving and restoring current warning state.
     1012  #pragma clang diagnostic push
     1013  #pragma clang diagnostic pop
     1014
     1015// Example of using Clang push'n'pop around two ignored warnings.
     1016  #pragma clang diagnostic push
     1017  #pragma clang diagnostic ignored "-Wmultichar"
     1018  #pragma clang diagnostic ignored "-Wconstant-conversion"
     1019  #pragma clang diagnostic ignored  "-Wunused-variable"
     1020  char b = 'df'; // Most unwisely ignoring ALL warnings.
     1021  #pragma clang diagnostic pop
     1022
     1023// Example of using macro for push and pop pragmas.
     1024  CLANG_DIAG_PRAGMA(push);
     1025  #pragma clang diagnostic ignored "-Wunused-variable"
     1026  int unused;
     1027  CLANG_DIAG_PRAGMA(pop);
     1028
     1029  // example of using macro to push warning state,suppress a warning and restore state.
     1030  CLANG_DIAG_OFF(unused-variable)
     1031  int unused_two;  // No warning from unused variable.
     1032  CLANG_DIAG_ON(unused-variable) //
     1033
     1034  int unused_too; // Expect an unused-variable warning!
     1035
     1036  return 0;
     1037}
     1038
     1039/*  Output:
     1040  Clang 3.1.0
     1041
     1042 clang++.exe -dD -Wall -Wextra   -c -g -Wall -I/i/boost-trunk -MMD -MP -MF build/Debug/MinGW_Clang-Windows/warnings_1.o.d -o build/Debug/MinGW_Clang-Windows/warnings_1.o warnings_1.cpp
     1043warnings_1.cpp:97:7: warning: unused variable 'unused_too' [-Wunused-variable]
     1044  int unused_too; // Expect an unused-variable warning!
     1045      ^
     10461 warning generated.
     1047 *
     1048 *
     1049 * but for MSVC
     1050 *
     1051 ClCompile:
     1052  warning_1.cpp
     1053warning_1.cpp(77): warning C4068: unknown pragma
     1054warning_1.cpp(78): warning C4068: unknown pragma
     1055warning_1.cpp(81): warning C4068: unknown pragma
     1056warning_1.cpp(82): warning C4068: unknown pragma
     1057warning_1.cpp(83): warning C4068: unknown pragma
     1058warning_1.cpp(84): warning C4068: unknown pragma
     1059warning_1.cpp(85): warning C4305: 'initializing' : truncation from 'int' to 'char'
     1060warning_1.cpp(85): warning C4309: 'initializing' : truncation of constant value
     1061warning_1.cpp(86): warning C4068: unknown pragma
     1062warning_1.cpp(90): warning C4068: unknown pragma
     1063warning_1.cpp(99): warning C4101: 'unused_too' : unreferenced local variable
     1064warning_1.cpp(96): warning C4101: 'unused_two' : unreferenced local variable
     1065warning_1.cpp(85): warning C4189: 'b' : local variable is initialized but not referenced
     1066warning_1.cpp(91): warning C4101: 'unused' : unreferenced local variable
     1067j:\cpp\svg\warning_1\warning_1.cpp(66): warning C4701: potentially uninitialized local variable 'x' used
     1068
     1069*/
     1070}}}
     1071
     1072showing that eliminating warnings is usually much less trouble.
     1073
     1074More info and experience needed on Clang.
    9591075
    9601076'''Intel'''