尽管有“-fallow-argument-mismatch”标志,但 Gfortran 类型不匹配错误

Gfortran type mismatch error despite "-fallow-argument-mismatch" flag

提问人:Manolete 提问时间:11/16/2023 最后编辑:Manolete 更新时间:11/18/2023 访问量:105

问:

Gfortran 10 添加了默认行为,使类型不匹配成为错误而不是警告。该标志可用于将错误降级为警告。但是,在同一个 fortran 文件中,并将 gcc 13 与 ,gfortran 会触发一些警告(如预期的那样)和此处的一个错误:-fallow-argument-mismatch-fallow-argument-mismatch

call test(ter,file,0,'legacy')

                                                      
subroutine test(ander,file,mmr,status)                                                                                                                    
  implicit none
  integer(kind=8) :: mmr
                ....                                                                                                                                                                                   

为什么这种特定的不匹配在某种程度上不同,以至于它不被视为警告?

我可以通过执行以下操作来解决此问题:

call test(ter,file,INT8(0),'legacy')

但是,我认为这是在编译时使用的原因。我的编译命令如下:-fallow-argument-mismatch

gfortran -mfma -O3 -m64 -Ofast -ftree-vectorize -ftree-vectorizer-verbose=0 -fPIC -ffree-form -ffree-line-length-none -fallow-invalid-boz -fallow-argument-mismatch -fbackslash -fno-fast-math -c mem.f90 -o mem.o 

预期为整数 0,1,>1 或 <0。mmr

Fortran Gfortran

评论

5赞 Vladimir F Героям слава 11/16/2023
将 0 传递到不同大小的整数中是非常错误的,它不是那些不符合标准的遗留技巧之一,而是在实践中有效的。这个是完全错误的。它可能纯粹是运气好,但在其他平台上它会失败。
4赞 francescalus 11/16/2023
为了强调最小可重现示例的重要性,请注意与外部过程相关的示例。很多过程不是外部的,编译器可能希望更加挑剔(正如我所希望的那样)。错误抑制是为了允许仍然使用重要的旧库,以完全非法的方式,不允许在现代代码中草率地编写。-fallow-argument-mismatchcall vital_external_sub(1); call vital_external_sub('a'); end
3赞 PierU 11/17/2023
关键是,正如 @VladimirF Героямслава 所提到的,gfortran 在这里报告的是一个严重的编码错误,而不仅仅是一个“超出标准”的伎俩。您不应保留未更正的代码。
2赞 PierU 11/17/2023
该标准不要求编译器跟踪和报告此类错误。不过,这绝对是一个错误。修复它的最简单方法是通过而不是 .此语法表示“kind=8 整数类型的零值”0_80
2赞 PierU 11/17/2023
最终结果是一样的。但是:可能在运行时计算,而在编译时设置;但更重要的是,该功能不是标准的,因此不能保证是便携式的。int8(0)0_8int8()

答:

3赞 francescalus 11/18/2023 #1

类型不匹配违反了 Fortran 标准对程序单位的限制。编译器不需要能够检测和报告此类违规行为,但可以选择这样做。

考虑(非 Fortran)程序:

program broken
  implicit none(external)
  external sub

  call sub(1)
  call sub(1.)
end program

这违反了 Fortran 标准(长期存在的)过程引用规则,许多编译器会告诉你这一点。从 GCC 10 开始,gfortran 默认会抱怨这一点,并提供选项允许仍然编译许多损坏的 Fortran 源代码,就像早期版本的 gfortran 编译它们一样。1-fallow-argument-mismatch

该选项描述如下:-fallow-argument-mismatch

       -fallow-argument-mismatch
           Some code contains calls to external procedures with
           mismatches between the calls and the procedure
           definition, or with mismatches between different
           calls. Such code is non-conforming, and will usually
           be flagged wi1th an error.  This options degrades the
           error to a warning, which can only be disabled by
           disabling all warnings vial -w.  Only a single
           occurrence per argument is flagged by this warning.
           -fallow-argument-mismatch is implied by -std=legacy.

注意“外部”。

非 Fortran 源

program brokeninternal
  implicit none

  call sub(1)

contains
  subroutine sub(x)
    real x
  end subroutine sub

end program brokeninternal

类型不匹配,不使用 不会让你侥幸逃脱。该过程是内部的,因此具有显式接口2;编译器已使用 Yonks 的显式接口来检查参数。“yonks”的类型,可以追溯到显式接口出现的时候。没有遗漏诊断或非法但有用的支持。-fallow-argument-mismatchsub


1 无论是否违反 Fortran 标准,这种损坏的 Fortran 程序都很有用。其他 Fortran 编译器已经抱怨了很长时间,但仍然让用户坚持编译它们。

2 外部过程可能具有显式接口,并且不允许此类不匹配。在某些情况下,GFORTRAN 可以(现在)检测与隐式接口的特征不匹配,特别是当外部过程在与引用它的位置相同的文件中定义时,并且可能会产生影响。-fallow-argument-mismatch-fallow-argument-mismatch

评论

0赞 steve 11/18/2023
简洁的答案。一点历史。gfortran 开发人员向 gfortran 引入了参数检查,他担心他的补丁会破坏许多遗留代码。在刚刚介绍了该选项之后,我建议他提供一个选项,以优雅地将错误降级为警告。这既是祝福(对用户而言),也是对诅咒(对 gfortran 错误报告而言)。-fallow-invalid-boz-fallow-argument-mismatch
0赞 francescalus 11/18/2023
@steve,我已经支持了足够多的用户,他们的答案是“修复你的代码,而不是责怪工具”,即使我从未成为真正的编译器开发人员。诊断是好的,但是的,必须有实用主义。