GCC 8 Release SeriesChanges, New Features, and Fixes


  • New command-line options have been added for the C++ compiler to control warnings:
    • -Wclass-memaccess warns when objects of non-trivial class types are manipulated in potentially unsafe ways by raw memory functions such as memcpy, or realloc. The warning helps detect calls that bypass user-defined constructors or copy-assignment operators, corrupt virtual table pointers, data members of const-qualified types or references, or member pointers. The warning also detects calls that would bypass access controls to data members. For example, a call such as:
       memcpy (&std::cout, &std::cerr, sizeof std::cout);
      results in
       

      warning:

      'void* memcpy(void*, const void*, long unsigned int)' writing to an object of type 'std::ostream' {aka 'class std::basic_ostream<char>'} with no trivial copy-assignment [

      -Wclass-memaccess

      ]
      The -Wclass-memaccess option is included in -Wall.
  • When reporting on attempts to access private fields of a class or struct, the C++ compiler will now offer fix-it hints showing how to use an accessor function to get at the field in question, if one exists.
    $ gcc accessor.cc
    

    accessor.cc:

    In function '

    void test(foo*)

    ':

    accessor.cc:12:12:

    error:

    '

    double foo::m_ratio

    ' is private within this context if (ptr->

    m_ratio

    >= 0.5)

    ^~~~~~~

    accessor.cc:7:10:

    note:

    declared private here double

    m_ratio

    ;

    ^~~~~~~

    accessor.cc:12:12:

    note:

    field '

    double foo::m_ratio

    ' can be accessed via '

    double foo::get_ratio() const

    ' if (ptr->

    m_ratio

    >= 0.5)

    ^~~~~~~

    get_ratio()

  • The C++ compiler can now give you a hint if you use a macro before it was defined (e.g. if you mess up the order of your #include directives):
    $ gcc ordering.cc
    

    ordering.cc:2:24:

    error:

    expected '

    ;

    ' at end of member declaration virtual void clone()

    const

    OVERRIDE { }

    ^~~~~

    ;

    ordering.cc:2:30:

    error:

    '

    OVERRIDE

    ' does not name a type virtual void clone() const

    OVERRIDE

    { }

    ^~~~~~~~

    ordering.cc:2:30:

    note:

    the macro '

    OVERRIDE

    ' had not yet been defined In file included from

    ordering.cc:5

    :

    c++11-compat.h:2:

    note:

    it was later defined here #define OVERRIDE override
  • The -Wold-style-cast diagnostic can now emit fix-it hints telling you when you can use a static_cast, const_cast, or reinterpret_cast.
    $ gcc -c old-style-cast-fixits.cc -Wold-style-cast
    

    old-style-cast-fixits.cc:

    In function '

    void test(void*)

    ':

    old-style-cast-fixits.cc:5:19:

    warning:

    use of old-style cast to '

    struct foo*

    ' [

    -Wold-style-cast

    ] foo *f = (foo *)

    ptr

    ;

    ^~~

    ----------

    static_cast<foo *> (ptr)

  • When reporting on problems within extern "C" linkage specifications, the C++ compiler will now display the location of the start of the extern "C".
    $ gcc -c extern-c.cc
    

    extern-c.cc:3:1:

    error:

    template with C linkage

    template

    <typename T> void test (void);

    ^~~~~~~~

    In file included from

    extern-c.cc:1

    :

    unclosed.h:1:1:

    note:

    '

    extern "C"

    ' linkage started here

    extern "C"

    {

    ^~~~~~~~~~

    extern-c.cc:3:39:

    error:

    expected '

    }

    ' at end of input template <typename T> void test (void)

    ;

    ^

    In file included from

    extern-c.cc:1

    :

    unclosed.h:1:12:

    note:

    to match this '

    {

    ' extern "C"

    {

    ^

  • When reporting on mismatching template types, the C++ compiler will now use color to highlight the mismatching parts of the template, and will elide the parameters that are common between two mismatching templates, printing [...] instead:
    $ gcc templates.cc
    

    templates.cc:

    In function '

    void test()

    ':

    templates.cc:9:8:

    error:

    could not convert '

    vector<double>()

    ' from '

    vector<double>

    ' to '

    vector<int>

    ' fn_1(

    vector<double> ()

    );

    ^~~~~~~~~~~~~~~~~

    templates.cc:10:8:

    error:

    could not convert '

    map<int, double>()

    ' from '

    map<[...],double>

    ' to '

    map<[...],int>

    ' fn_2(

    map<int, double>()

    );

    ^~~~~~~~~~~~~~~~~~

    Those [...] elided parameters can be seen using -fno-elide-type:
    $ gcc templates.cc -fno-elide-type
    

    templates.cc:

    In function '

    void test()

    ':

    templates.cc:9:8:

    error:

    could not convert '

    vector<double>()

    ' from '

    vector<double>

    ' to '

    vector<int>

    ' fn_1(

    vector<double> ()

    );

    ^~~~~~~~~~~~~~~~~

    templates.cc:10:8:

    error:

    could not convert '

    map<int, double>()

    ' from '

    map<int,double>

    ' to '

    map<int,int>

    ' fn_2(

    map<int, double>()

    );

    ^~~~~~~~~~~~~~~~~~

    The C++ compiler has also gained an option -fdiagnostics-show-template-tree which visualizes such mismatching templates in a hierarchical form:
    $ gcc templates-2.cc -fdiagnostics-show-template-tree
    

    templates-2.cc:

    In function '

    void test()

    ':

    templates-2.cc:9:8:

    error:

    could not convert '

    vector<double>()

    ' from '

    vector<double>

    ' to '

    vector<int>

    ' vector< [

    double

    !=

    int

    ]> fn_1(

    vector<double> ()

    );

    ^~~~~~~~~~~~~~~~~

    templates-2.cc:10:8:

    error:

    could not convert '

    map<map<int, vector<double> >, vector<double> >()

    ' from '

    map<map<[...],vector<double>>,vector<double>>

    ' to '

    map<map<[...],vector<float>>,vector<float>>

    ' map< map< [...], vector< [

    double

    !=

    float

    ]>>, vector< [

    double

    !=

    float

    ]>> fn_2(

    map<map<int, vector<double>>, vector<double>> ()

    );

    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    which again works with -fno-elide-type:
    $ gcc templates-2.cc -fdiagnostics-show-template-tree -fno-elide-type
    

    templates-2.cc:

    In function '

    void test()

    ':

    templates-2.cc:9:8:

    error:

    could not convert '

    vector<double>()

    ' from '

    vector<double>

    ' to '

    vector<int>

    ' vector< [

    double

    !=

    int

    ]> fn_1(

    vector<double> ()

    );

    ^~~~~~~~~~~~~~~~~

    templates-2.cc:10:8:

    error:

    could not convert '

    map<map<int, vector<double> >, vector<double> >()

    ' from '

    map<map<int,vector<double>>,vector<double>>

    ' to '

    map<map<int,vector<float>>,vector<float>>

    ' map< map< int, vector< [

    double

    !=

    float

    ]>>, vector< [

    double

    !=

    float

    ]>> fn_2(

    map<map<int, vector<double>>, vector<double>> ()

    );

    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~