我可以使用哪些gcc编译器选项来编译gfortran?

3
我学习了关于gfortran选项总结,但没有找到检测整数溢出的编译器选项。后来我在这里发现了GCC(GNU编译器集合)标志选项-fsanitize=signed-integer-overflow并在调用gfortran时使用它。它有效 - 整数溢出可以在运行时检测到!
那么-fsanitize=signed-integer-overflow在这里做了什么?只是向由gfortran生成的机器代码添加一些检查整数溢出的机器级别代码吗? GCC(GNU编译器集合)标志选项gfortran编译器选项之间有什么关系?我可以为gfortran,g++等使用哪些gcc编译器选项?
2个回答

5

有GCC - GNU编译器集合。它共享通用的后端和中间层,并具有不同语言的前端。例如C、C++和Fortran的前端,通常通过命令gccg++gfortran调用。

实际上更为复杂,您可以在Fortran源文件上调用gcc,在C源文件上调用gfortran,几乎会以相同方式工作,除了链接库(还有其他一些细微之处)。适当的前端将基于文件扩展名或请求的语言进行调用。

您可以查看所有提到的前端的几乎所有GCC(而不仅仅是gcc)标志。有一些特定于语言的标志。通常会收到类似以下的警告:

gfortran -fcheck=all source.c
cc1: warning: command line option ‘-fcheck=all’ is valid for Fortran but not for C

但是文件会编译正常,选项只是被忽略了并且您将收到有关此警告。请注意,它是一个C文件,并且通过“gfortran”命令进行了编译。

据我所知,清理选项与语言无关,并且适用于GCC中实现的多种语言,可能会有一些明显的特定于语言的检查例外情况。特别地,您所询问的-fsanitize=signed-integer-overflow在C和C++中都可以完美工作。 在C和C++中,有符号整数溢出是未定义行为,在Fortran标准中也不允许(这实际上意味着相同,只是Fortran使用不同的单词)。


抱歉造成困惑,我所说的gcc实际上是指GCC(问题已经更新)。如果使用了错误的标志选项,编译器会发出警告,这很棒。然而,对于那些不会抱怨的选项,有些是不起作用的!!!例如,-fsanitize=bounds-fsanitize=integer-divide-by-zero都不适用于gfortran。因此,我猜当调用gfortran编译器时,仍然可以使用来自GCC的非特定语言的标志选项,但不应依赖这些标志选项。只有针对特定编译器记录的那些编译器选项才能保证起作用。 - Kevin Powell
2
GFortran手册中提到的选项是在GFortran前端实现的,因此它们是特定于Fortran的。GCC手册包含了特定于C、C++的选项,通用选项以及仅适用于特定目标(后端)的选项。其中一些选项可能与GFortran完美地配合使用,而另一些则可能不行。 - janneb

3

这并不是对你问题的一个非常精确的回答,但当学习编译器时,一个“啊哈!”时刻是学习到gcc(GNU Compiler Collection)和llvm一样,是一个三阶段编译器的例子。

  • “前端”解析你感兴趣的任何语言的语法,并输出一个抽象语法树(AST),它以一种与语言无关的方式表示你的程序。
  • 然后,“中间件”(可怕的名称,但“聪明之处”)将该AST重新组织为另一个AST,其在语义上等效但更容易转换为机器代码。
  • 然后,“后端”将重新组织的AST转换为某个处理器的汇编代码,可能会沿途执行特定于平台的微优化。

这就是为什么(巨大数量的)gcc/llvm选项出乎意料地适用于(表面上非常不同的)不同语言的原因。其中一些选项是特定于C、Fortran、Objective-C或其他语言的,但大多数选项(可能)涉及中间和最后几个部分,因此适用于gcc/llvm支持的所有语言。

因此,各种选项都是针对阶段1、2或3特定的,但可能没有方便的标签;然而,有了这个想法,您可以合理地直觉出与您感兴趣的特定语言相关或不相关的内容。
(正是出于这种原因,我会毫不犹豫地声称CC++FortranJavaPerlPython本质上是一种语言,只有微不足道的语法和库细节区别方言。)

感谢您的深入解释!不过,当调用特定语言编译器(例如 gfortran)并使用某些 GCC 标志选项时,不好的一点是编译器不会发出警告,而且标志选项也不起作用。 - Kevin Powell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接