在 Fortran 中使用函数结果作为字符长度

问题描述 投票:0回答:1

考虑以下最小工作示例:

module lib
    type t
    contains
        procedure::f,g
    end type
contains
    integer function f(this)
        class(t),intent(in)::this
        f=10
    end
    function g(this)result(r)
        class(t),intent(in)::this
        character(len=this%f())::r
        r='42'
    end
end

program prog
    use lib
    type(t)::o
    print*,o%g()
end

使用 GNU (gfortran 11.1.0) 编译器编译此代码会导致以下消息:

f951: internal compiler error: Segmentation fault
0x16463d7 internal_error(char const*, ...)
    ???:0
0x64b47c gfc_find_derived_vtab(gfc_symbol*)
    ???:0
0x672605 gfc_reduce_init_expr(gfc_expr*)
    ???:0
0x6572e3 gfc_match_char_spec(gfc_typespec*)
    ???:0
0x65e227 gfc_match_decl_type_spec(gfc_typespec*, int)
    ???:0
0x65f93c gfc_match_data_decl()
    ???:0
0x6d6236 gfc_parse_file()
    ???:0
Please submit a full bug report

消息说这是一个编译器错误,但我不太确定。 NAG (nagfor 7.1) 编译器也无法编译带有

Error: line 13: Reference to non-specification function F in specification expression
的代码。但是,Intel(ifort 2021.8.0、ifx 2023.0.0)和 Nvidia(nvfortran 22.9)编译器编译代码成功。前两个编译器(GNU 和 NAG)中的问题是由行
character(len=this%f())::r
.

引起的

Fortran 标准是否允许使用函数的结果声明字符长度(在自动分配中)(这里

f
)?它是 GNU 编译器的错误还是 Intel 和 Nvidia 编译器的功能?

compiler-errors fortran gfortran intel-fortran
1个回答
1
投票

一些函数可以用来给出字符函数结果的长度;这里使用的特定功能不能。

第一:编译器不应该崩溃。您在 gfortran 中看到的是一个内部编译器错误 (ICE),一个错误。无论所提供的代码是否有效 Fortran,ICE 都是错误。1

NAG 编译器在拒绝您的代码时引入的术语是是否允许使用函数的关键。字符函数结果的长度必须是 规范表达式2 关于如何制作规范表达式的规则相当复杂(有关更多详细信息,请参见 Fortran 2018 10.1.11 和此处的其他问答)但原因

F
这里被 nagfor 拒绝是因为
F
不是 pure 函数。

要使

F
成为规范函数,它必须是纯函数(F2018 10.1.11注1):

纯净的要求确保它们不会有副作用 这可能会影响在同一规范部分中声明的其他对象。

至少对于我测试过的 gfortran 版本,您可以绕过 ICE,一旦您使

F
变纯,通过将规范表达式更改为:

character(len=f(this))::r

最后,请注意,不能自信地说 Intel/NVIDIA 编译器错误地接受了这段代码。该代码不是有效的 Fortran,因此编译器可以选择执行任何操作,包括接受它作为扩展。这不是编译器需要能够诊断您的错误的情况。 (人们仍然可以将其称为编译器错误,因为这种特殊的违规行为可能很容易诊断并且很容易看到。)


1这不是真的真的。如果代码不是有效的 Fortran 代码,那么允许编译器做任何响应(只要它能够报告它需要能够检测和报告的那些缺陷)。崩溃是它被允许做的事情,尽管编译器供应商通常认为 ICE 是一个错误,即使它是 Fortran 标准下允许的响应:这是一种糟糕的用户体验。

2这同样适用于数组边界和更广泛的过程的自动数据对象。

© www.soinside.com 2019 - 2024. All rights reserved.