Search code examples
gccgcc-warning

How to query GCC warnings for C++?


GCC allows querying available warning flags specific for C++ language with the syntax:

g++ -Q --help=warning,c++

Adding warning flags to the call includes them in the result:

g++ -Wall -Q --help=warning,c++

However, it seems the call is done from the C point of view and I don't know how to do it from the C++ point of view. If the call includes C++-only warning, like:

g++ -Wnon-virtual-dtor -Q --help=warning,c++

the output contains a message:

cc1: warning: command line option ‘-Wnon-virtual-dtor’ is valid for C++/ObjC++ but not for C

and still shows the warning as disabled:

  -Wnon-virtual-dtor                    [disabled]

Note, that this happens regardless of whether the call is done using g++ or gcc.

The same with C-only -Wbad-function-cast behaves in an expected way:

gcc -Wbad-function-cast -Q --help=warning,c

There is no extra message and reported warning status changes between [disabled] and [enabled]. Again, regardless of whether g++ or gcc is used.

I'm using GCC version 7.3.0. Although the issue seems to apply to many if not all versions. It can be observed through Compiler Explorer.

So, is there a way to do this query with respect to given language?


Solution

  • Yes, your observations are correct.

    Probably this is not the intended behavior, and if you care about this feature, then I suggest reporting it upstream.

    Note that this works, however:

    touch 1.cc
    g++ -Wnon-virtual-dtor -Q --help=warning,c++ 1.cc
    

    I.e. if there's an input file with a proper extension, then the correct compiler proper executable is invoked: cc1plus, not cc1. The latter is the default if no input files are present. I did some quick debugging, and here's how that happens:

    // gcc.c:
    driver::do_spec_on_infiles () const
    {
      ...
      for (i = 0; (int) i < n_infiles; i++)
        {
          ...
          /* Figure out which compiler from the file's suffix.  */
    
          input_file_compiler
            = lookup_compiler (infiles[i].name, input_filename_length,
                               infiles[i].language);
    
          if (input_file_compiler)
            {
              ...
                  value = do_spec (input_file_compiler->spec);
    
    

    And input_file_compiler at that point is the C compiler, because

    p n_infiles
    $9 = 1
    (gdb) p infiles[0]
    $10 = {name = 0x4cbfb0 "help-dummy", language = 0x4cbfae "c", incompiler = 0x58a920, compiled = false, preprocessed = false}
    

    Here's how the dummy file got created (function process_command in the same file):

      if (n_infiles == 0
          && (print_subprocess_help || print_help_list || print_version))
        {
          /* Create a dummy input file, so that we can pass
             the help option on to the various sub-processes.  */
          add_infile ("help-dummy", "c");
        }