代码之家  ›  专栏  ›  技术社区  ›  Matt Joiner

C的有用GCC标志

  •  149
  • Matt Joiner  · 技术社区  · 14 年前

    -Wall ,和设置 -std=XXX ,还有什么其他真正有用但鲜为人知的编译器标志可用于C?

    我特别感兴趣的是任何额外的警告,和/或在某些情况下将警告转化为错误,以绝对减少任何意外的类型不匹配。

    24 回复  |  直到 4 年前
        1
  •  66
  •   caf    14 年前

    几个 -f 代码生成选项很有趣:

    • 这个 -ftrapv

    • -fverbose-asm 如果您使用 -S 为了检查程序集输出,它添加了一些有用的注释。

    • -finstrument-functions 添加代码以在每个函数入口和出口点调用用户提供的分析函数。

        2
  •  144
  •   Alok Singhal    14 年前

    这是我的:

    • -Wextra -Wall :基本要求。
    • -Wfloat-equal :很有用,因为通常测试浮点数的相等性是不好的。
    • -Wundef :如果在中计算未初始化的标识符,则发出警告 #if
    • -Wshadow :当局部变量对另一个局部变量、参数或全局变量进行阴影处理时,或当对内置函数进行阴影处理时,发出警告。
    • -Wpointer-arith :如果有任何内容取决于函数或函数的大小,则发出警告 void .
    • -Wcast-align :每当投射指针时发出警告,以增加所需的目标对齐。例如,如果 char * 被投给一个 int * 在只能以两字节或四字节边界访问整数的机器上。
    • -Wstrict-prototypes :如果在未指定参数类型的情况下声明或定义函数,则发出警告。
    • -Wstrict-overflow=5
    • -Wwrite-strings :为字符串常量指定类型 const char[ ] 所以把一个人的地址复制到一个- const char *
    • -Waggregate-return :如果定义或调用了任何返回结构或联合的函数,则发出警告。
    • -Wcast-qual :每当强制转换指针以从目标类型中删除类型限定符时发出警告 * .
    • -Wswitch-default switch 语句没有 default * .
    • -Wswitch-enum 转换 case * .
    • -Wconversion :警告可能更改值的隐式转换 .
    • -Wunreachable-code :如果编译器检测到永远不会执行代码,则发出警告 *

    标记的 *

        3
  •  54
  •   Gilles 'SO- stop being evil'    14 年前

    -O 或以上( -O1 -O2 , -Os 等)。在默认的优化级别,gcc追求编译速度,并且没有做足够的分析来警告诸如单位化变量之类的事情。

    -Werror 策略,因为不停止编译的警告往往会被忽略。

    -Wall

    -Wextra 倾向于标记通用的合法代码。它们可能对代码评审有用(尽管lint风格的程序发现更多的陷阱更灵活),但我不会在正常开发中启用它们。

    -Wfloat-equal 如果项目中的开发人员不熟悉浮点,那么这是个好主意,如果他们不熟悉浮点,那么这是个坏主意。

    -Winit-self 是有用的;我想知道为什么它不包括在 -Wuninitialized

    -Wpointer-arith 如果您的大部分可移植代码都不能与 -pedantic .

        4
  •  39
  •   catphive    13 年前
    -save-temps
    

        5
  •  36
  •   user257111 user257111    14 年前

    我很惊讶还没有人这么说——就我而言,最有用的标志是 -g 它将调试信息放入可执行文件中,这样您就可以对其进行调试并逐步遍历源代码(除非您精通并阅读汇编等) stepi (命令)程序执行时的。

        6
  •  35
  •   Nordic Mainframe    14 年前

    -口盖 --向所有有风险的指针操作添加运行时检查以捕获UB。这将有效地再次免疫程序缓冲区溢出,并帮助捕获各种悬空指针。

    下面是一个演示:

    $ cat mf.c 
    int main()
    {
     int a[10];
     a[10]=1; // <-- o noes, line 4
    }
    
    $ gcc -fmudflap mf.c -lmudflap
    $ ./a.out 
    *******
    mudflap violation 1 (check/write): time=1280862302.170759 ptr=0x7fff96eb3d00 size=44
    pc=0x7f3a575503c1 location=`mf.c:4:2 (main)'
          /usr/lib/libmudflap.so.0(__mf_check+0x41) [0x7f3a575503c1]
          ./a.out(main+0x90) [0x400a54]
          /lib/libc.so.6(__libc_start_main+0xfd) [0x7f3a571e2c4d]
    Nearby object 1: checked region begins 0B into and ends 4B after
    mudflap object 0xf9c560: name=`mf.c:3:6 (main) a'
    bounds=[0x7fff96eb3d00,0x7fff96eb3d27] size=40 area=stack check=0r/3w liveness=3
    alloc time=1280862302.170749 pc=0x7f3a57550cb1
    number of nearby objects: 1
    
        7
  •  21
  •   Community c0D3l0g1c    4 年前

    @file
    

    把上面所有好的标志(你们都指定了)放在一个“文件”中,并使用上面的这个标志将该文件中的所有标志一起使用。

    如:

    文件:compilerFlags

    -墙

    -标准=c99

    -韦斯特拉

    然后编译:

    gcc yourSourceFile @compilerFlags
    
        8
  •  15
  •   Jens Gustedt    14 年前

    -march=native 为您正在编译的平台(=芯片)生成优化的代码

        9
  •  15
  •   sizzzzlerz    14 年前

    如果需要知道编译器预定义的预处理器标志:

    echo | gcc -E -dM -
    
        10
  •  13
  •   Michael Burr    14 年前

    它对检测错误并没有真正的帮助,但是很少提到的 -masm=intel -S 检查组件的输出要好多好多了。

        11
  •  10
  •   David Cary    14 年前

    我的makefile通常包含

      CFLAGS= -Wall -Wextra -Weffc++ -Os -ggdb
      ...
      g++ $(CFLAGS) -o junk $<
      gcc $(CFLAGS) -o $@ $<
      rm -f junk
    

    需要 为了便于移植到某个 仍然

    1. C++编译器接受-WebFC++选项,偶尔会给我一些有用的提示,如果我只在C中编译,我会错过这些有用的提示。

    是的,我是一个乐观得无可救药的波兰人,她一直这么想 当然 现在任何一个月,一个平台要么宣布过时,要么获得一个体面的C++编译器,我们终于可以切换到C++。在我看来,这是不可避免的——唯一的问题是,这是在管理层最终给每个人发了一匹小马之前还是之后发生的

        12
  •  10
  •   Matt Joiner    14 年前

    -Werror-implicit-function-declaration
    

        13
  •  9
  •   ninjalj    14 年前
    -Wstrict-prototypes -Wmissing-prototypes
    
        14
  •  8
  •   Johan    14 年前
    man gcc
    

        15
  •  6
  •   RWS    14 年前

    好, -Wextra 也应该是标准的。 -Werror 将警告变为错误(可以 非常 烦人,尤其是在编译时没有 -Wno-unused-result -pedantic 结合 std=c89 如果您使用C99功能,将提供其他警告。

    但仅此而已。你不能把一个C编译器调整成比C本身更能保存类型的东西。

        16
  •  6
  •   catphive    13 年前

    -M*

    下面是一个使用-MD和-MP的非常通用的makefile示例,它将编译一个充满c++源文件和头文件的目录,并自动找出所有依赖项:

    CPPFLAGS += -MD -MP                                         
    SRC = $(wildcard *.cpp)                                                       
    
    my_executable: $(SRC:%.cpp=%.o)                                                        
            g++ $(LDFLAGS) -o $@ $^                                               
    
    -include $(SRC:%.cpp=%.d)
    

    以下是一篇博文,对其进行了更深入的讨论: http://www.microhowto.info/howto/automatically_generate_makefile_dependencies.html

        17
  •  6
  •   Scooter    7 年前

    -Werror gcc manual page

        18
  •  4
  •   Mike    12 年前

    -Wfloat-equal

    发件人: http://mces.blogspot.com/2005/07/char-const-argv.html

    我喜欢的另一个新警告是-Wfloat equal。当浮点数处于相等条件时,它就会发出警告。那是布莱恩!如果你每个人都编写了计算机图形学或(更糟的:)计算几何算法,你就知道没有两个浮点数是相等的。。。

        19
  •  4
  •   Community c0D3l0g1c    7 年前

    my post :

    这个 -Wformat=2 旗帜

    -Wformat printf scanf

    最重要的是( according to the GCC manual ):

    -W格式 包含在 -Wall . 为了更好地控制格式检查的某些方面,选项 -Wformat-y2k -Wno-format-extra-args , -Wno-format-zero-length -Wformat-nonliteral , -Wformat-security 是可用的,但不包括在墙上`

    -墙 并不意味着你拥有一切

        20
  •  3
  •   Vasiliy Sharapov    14 年前

    我有时用 -s 对于更小的可执行文件:

    -s
        Remove all symbol table and relocation information from the executable.
    

    http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html#Link-Options

        21
  •  3
  •   t0mm13b    14 年前

    虽然这个答案可能有点离题,而且这个问题对我来说是值得的+1,因为

    我特别感兴趣的是任何额外的警告,和/或在某些情况下将警告转化为错误,以绝对减少任何意外的类型不匹配。
    有一种工具应该被发现 全部 splint 与gcc或其他编译器相比,IMHO在发现错误方面做得更好。你的工具箱里有一个很好的工具。

    通过lint类型的工具(如splint)进行静态检查应该是编译器工具链的一部分。

        22
  •  2
  •   Matthew Slattery    14 年前

    除了 -Wall ,的 -W -Wextra -W型 -韦斯特拉

    也有更多的警告,这两个都没有启用,一般情况下,对于那些更可疑的坏东西。可用选项集取决于您使用的gcc版本-consult man gcc info gcc online documentation 对于您感兴趣的特定gcc版本。以及 -pedantic 发布所使用的特定标准要求的所有警告(这取决于其他选项,例如 -std=xxx -ansi

    和/或在某些情况下将警告转化为错误,以绝对减少任何意外类型 不匹配。

    -Werror 将所有警告变为错误。不过,我不认为gcc允许您有选择地对特定警告执行此操作。

    -沃罗 ),因为来自外部库的头文件可能会使其中一些文件跳闸( 尤其是在这方面,以我的经验来看,往往毫无帮助。)

        23
  •  1
  •   StaceyGirl    6 年前
    • -Wmissing-prototypes
    • -Wformat-security :警告使用表示可能存在安全问题的格式函数。目前,这会警告有关呼叫 printf scanf 格式字符串不是字符串文字且没有格式参数的函数
        24
  •  1
  •   ChrisZZ    5 年前
    • -Werror=return-type :当函数在gcc中没有返回时强制执行错误。它是 /we4716

    • -Werror=implicit-function-declaration /we4013 在Visual Studio中。

    • -Werror=incompatible-pointer-types :当指针的类型与预期的指针类型不匹配时,强制执行错误。它是 /we4133 在Visual Studio中。

    if (CMAKE_SYSTEM_NAME MATCHES "Windows")
        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /we4013 /we4133 /we4716")
    elseif (CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME MATCHES "Darwin")
        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=implicit-function-declaration -Werror=incompatible-pointer-types -Werror=return-type")
    endif()