Changes between Version 38 and Version 39 of Guidelines/MaintenanceGuidelines


Ignore:
Timestamp:
Feb 3, 2010, 8:17:14 PM (13 years ago)
Author:
phorgan1
Comment:

Started adding information about gcc warnings

Legend:

Unmodified
Added
Removed
Modified
  • Guidelines/MaintenanceGuidelines

    v38 v39  
    903903More information needed here!
    904904
    905 ||? || class does not have a  virtual destructor||Suppress or provide a virtual destructor.||??||
     905== Individual Warnings ==
     906'''comparison between signed and unsigned integer expressions'''
     907
     908    '''-Wsign-compare''' - enable the warning (also turned on by -Wextra)[[BR]]
     909    '''-Wno-sign-compare''' - disable the warning[[BR]]
     910
     911    Almost always points to a real issue. The ranges of these are obviously
     912    different, for example signed char -128 - 127 and unsigned char 0 - 255 for
     913
     914                    range               bit pattern
     915    signed char     -128 to 127     01111111 to 10000000
     916    unsigned char    0 to 255       00000000 to 11111111
     917
     918    That means: signed char     unsigned char
     919      0 to 127      +               +
     920    128 to 255      -               +
     921
     922    In the range from 128 to 255 a comparison from one to the other makes no
     923    sense.  They can have the same bit pattern, yet test as not equal.  This
     924    is the source of many subtle and hard to find bugs.
     925
     926    The same problem can occur with all of the integral types. For example with
     927    16-bit short int unsigned ranges from -32768 to 32767, and the signed short
     928    ranges from 0 to 65535.
     929
     930    To fix, if you are sure that all the values for both things being compared
     931    fall into the overlap where their values are the same, you can static_cast
     932    one type to the other, if you must, but if you can change one of the types
     933    it's a better solution.  If you are sure that you can fit all values into
     934    the compared range, i.e. positive numbers from
     935    0 to (1<<(sizeof(IntegralType)*8-1))-1, it would make more sense to
     936    declare the signed one as an unsigned equivalent, (perhaps size_t).  In
     937    general, if you don't intend for a variable to ever have negative values,
     938    take advantage of the diagnostic capabilities of the compiler and don't
     939    declare it as an unsigned type.  After you've done this, if you see the
     940    warning again for one of these same variables, it is warning you of this
     941    same danger again.
     942
     943    This often shows up with loop counters.  We all learned to use int, but
     944    if it's truly counting only positive numbers, size_t is better.
     945
     946'''missing braces around initializer for ‘main()::X'''
     947
     948    '''-Wmissing-braces''' - enable the warning (also turned on by -Wall)[[BR]]
     949    '''-Wno-missing-braces''' - disable the warning
     950
     951    This warning is trying to let you know that what you think you're
     952    initializing may not actually be what you're initializing.
     953
     954
     955{{{
     956        struct X { int i; int j;};
     957        struct Y { struct X x; int j; };
     958
     959        Y y={1,2};
     960        return 0;
     961
     962}}}
     963
     964    The above example initializes both the elements of X in Y, but doesn't
     965    initialize j.  Change to:
     966
     967        {{{Y y={{1},2};}}}
     968
     969    to initialize half of X and all of Y, or better something like:
     970
     971        {{{Y y={{1,2},3};}}}
     972
     973    The same kind of problem can come up with:
     974
     975        {{{int a[2][2]={ 0, 1, 2 };}}}
     976
     977    versus:
     978
     979        {{{int a[2][2]={ {0,1},2};}}} or {{{int a[2][2]={ 0, {1,2}};}}}
     980
     981'''deprecated conversion from string constant to ‘char*’'''
     982    '''-Wwrite-strings''' - enable this warning (disabled by default for C and enabled by default for C++)
     983    '''-Wno-write-strings''' - disable this warning
     984
     985        For C will warn about trying to modify string constants, but only if defined const.
     986        For C++ often symptomatic of a real bug since string literals are not writeable in C++.
     987
     988        This one shows up when you have a string literal, like "Hello world!" which
     989        is arguably const data, and you assign it no a non-const char* either
     990        directly or via passing as an argument to a functions which expects a non-const char *.
     991        both:
     992            {{{
     993               char* cp="Hello world!";
     994            }}}
     995        and
     996            {{{
     997                void foo(char *cp);
     998                foo("Hello world")
     999            }}}
     1000        will get this warning because you're using a string literal where a char*
     1001        is expected.  If you say, so what?  See if you can predict what will print
     1002        in the example below.
     1003
     1004        {{{
     1005        #include <iostream>
     1006
     1007        void
     1008        foo(char *cp)
     1009        {
     1010            cp[0]='W';
     1011        }
     1012
     1013        int main()
     1014        {
     1015                char *str="Hello, world";
     1016                foo(str);
     1017                std::cout << str << std::endl;
     1018        }
     1019        }}}
     1020
     1021        If you said that Wello, world will print, think again.  Your most likely
     1022        output is something like:
     1023                '''Segmentation fault (core dumped)'''
     1024        A string literal is put into a section that is read only and trying to
     1025        write to it makes things blow up!
     1026
     1027        The right fix is to make anything that a string literal can be assigned
     1028        to a const char*.
     1029        Unfortunately, sometimes you can't fix the problem at the source, because
     1030        it's someone else's code, and you can't change the declaration.  For
     1031        example, if you had this function:
     1032
     1033        {{{
     1034        int PyArg_ParseTupleAndKeywords(PyObject *arg, PyObject *kwdict,
     1035                                char *format, char **kwlist, ...);
     1036        }}}
     1037
     1038    and you had a keyword list to pass it like this:
     1039
     1040        {{{
     1041        static char *kwlist[] = {"fget", "fset", "fdel", "doc", 0};
     1042                if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOO:property",
     1043                                          kwlist, &get, &set, &del, &doc))
     1044        }}}
     1045
     1046        you would get the warning on the kwlist assignment, but when you change
     1047        it to:
     1048
     1049        {{{
     1050        static const char *kwlist[] = {"fget", "fset", "fdel", "doc", 0};
     1051        }}}
     1052
     1053        you'll get:
     1054
     1055            error: invalid conversion from ‘const char**’ to ‘char**’
     1056
     1057        unless you change the call to:
     1058
     1059        {{{
     1060        if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOO:property",
     1061                                          const_cast<char **>(kwlist), &get, &set, &del, &doc))
     1062        }}}
     1063
     1064        annoyingly having to incorrectly cast away the constness of kwlist.
     1065        Now the code is arguably correct and it wasn't before.
     1066
     1067 |? || class does not have a  virtual destructor||Suppress or provide a virtual destructor.||??||
    9061068
    9071069'''Intel'''