How to disable GCC warnings for a few lines of code

后端 未结 9 756
我寻月下人不归
我寻月下人不归 2020-11-22 08:32

In Visual C++, it\'s possible to use #pragma warning (disable: ...). Also I found that in GCC you can override per file compiler flags. How can I do this for \"next line\",

9条回答
  •  盖世英雄少女心
    2020-11-22 09:23

    TL;DR: If it works, avoid, or use specifiers like __attribute__, otherwise _Pragma.

    This is a short version of my blog article Suppressing Warnings in GCC and Clang.

    Consider the following Makefile

    CPPFLAGS:=-std=c11 -W -Wall -pedantic -Werror
    
    .PHONY: all
    all: puts
    

    for building the following puts.c source code

    #include 
    
    int main(int argc, const char *argv[])
    {
        while (*++argv) puts(*argv);
        return 0;
    }
    

    It will not compile because argc is unused, and the settings are hardcore (-W -Wall -pedantic -Werror).

    There are 5 things you could do:

    • Improve the source code, if possible
    • Use a declaration specifier, like __attribute__
    • Use _Pragma
    • Use #pragma
    • Use a command line option.

    Improving the source

    The first attempt should be checking if the source code can be improved to get rid of the warning. In this case we don't want to change the algorithm just because of that, as argc is redundant with !*argv (NULL after last element).

    Using a declaration specifier, like __attribute__

    #include 
    
    int main(__attribute__((unused)) int argc, const char *argv[])
    {
        while (*++argv) puts(*argv);
        return 0;
    }
    

    If you're lucky, the standard provides a specifier for your situation, like _Noreturn.

    __attribute__ is proprietary GCC extension (supported by Clang and some other compilers like armcc as well) and will not be understood by many other compilers. Put __attribute__((unused)) inside a macro if you want portable code.

    _Pragma operator

    _Pragma can be used as an alternative to #pragma.

    #include 
    
    _Pragma("GCC diagnostic push")
    _Pragma("GCC diagnostic ignored \"-Wunused-parameter\"")
    
    int main(int argc, const char *argv[])
    {
        while (*++argv) puts(*argv);
        return 0;
    }
    _Pragma("GCC diagnostic pop")
    

    The main advantage of the _Pragma operator is that you could put it inside macros, which is not possible with the #pragma directive.

    Downside: It's almost a tactical nuke, as it works line-based instead of declaration-based.

    The _Pragma operator was introduced in C99.

    #pragma directive.

    We could change the source code to suppress the warning for a region of code, typically an entire function:

    #include 
    
    #pragma GCC diagnostic push
    #pragma GCC diagnostic ignored "-Wunused-parameter"
    int main(int argc, const char *argv[])
    {
        while (*++argc) puts(*argv);
        return 0;
    }
    #pragma GCC diagnostic pop
    

    Downside: It's almost a tactical nuke, as it works line-based instead of declaration-based.

    Note that a similar syntax exists in clang.

    Suppressing the warning on the command line for a single file

    We could add the following line to the Makefile to suppress the warning specifically for puts:

    CPPFLAGS:=-std=c11 -W -Wall -pedantic -Werror
    
    .PHONY: all
    all: puts
    
    puts.o: CPPFLAGS+=-Wno-unused-parameter
    

    This is probably not want you want in your particular case, but it may help other reads who are in similar situations.

提交回复
热议问题