如何在fortran编译器中指定声明的变量不应潜在地视为隐式函数声明
我很惊讶:如何在fortran编译器中指定声明的变量不应潜在地视为隐式函数声明,fortran,gfortran,intel-fortran,Fortran,Gfortran,Intel Fortran,我很惊讶: subroutine test (es, f) ! implicit none ! double precision es double precision f f=es(1,2) ! return end 编译时没有任何错误或警告:es未使用维度声明 我知道es被视为一个函数 但是当链接时,考虑到缺少的符号es,没有错误 查看汇编程序es(1,2)对应于调用rdx,因此没有链接错误 为了避免
subroutine test (es, f)
!
implicit none
!
double precision es
double precision f
f=es(1,2)
!
return
end
编译时没有任何错误或警告:es
未使用维度声明
我知道es
被视为一个函数
但是当链接时,考虑到缺少的符号es
,没有错误
查看汇编程序es(1,2)
对应于调用rdx
,因此没有链接错误
为了避免这个问题,我可以将es
声明为double-precision,intent(inout)
,然后我得到:
错误:过程属性与位于的“es”中的意图属性冲突
这是我第一次期待的
问题
是否有编译器选项(ifort或gfortran)强制将声明的变量视为intent(inout)
,而不是过程调用
先谢谢你
Ps:我有一个遗留代码,我不想在任何地方添加intent(inout)
来检测这种误解。“但是在链接时,考虑到缺少的符号es,没有错误!”
不应该有es
是伪参数的名称,而不是要传递到那里的实际过程的名称。实际上,在大多数实现中,代码会试图将变量指针作为函数地址调用,这会导致某种错误。要么执行不可执行代码,要么执行无效指令,要么执行病毒代码,这些代码被入侵者小心地放在堆栈或堆的正确位置
“是否有编译器选项(ifort或gfortran)强制将声明的变量视为意图(inout),而不是过程调用?”
不,即使是这样,它也会破坏代码语义,这是一件坏事(TM)。任何人在其他地方使用该代码,或者没有该选项,都将受到惩罚。尤其是它可能会造成危险的代码漏洞,这是不允许这样做的明显原因
最好明确地说,尽管我相信您已经意识到这一点,并且只需要一个诊断工具来警告您: 数组的正确声明涉及其维度,如
double precision es(1,*)
还要注意,编译器在调用过程时能够检查类似的错误。Gfortran将发现调用代码何时位于同一文件中,有时甚至是Intel(当启用了
-warn interfaces
时)。启用链接时间优化也有助于找到它。当然,现代Fortran应该使用模块
考虑:
subroutine test (es, f)
!
implicit none
!
double precision es
double precision f
f=es(1,2)
!
return
end
double precision a(2,1), b
call test(a, b)
end
由于调用位于同一文件中,gfortran将自动识别问题,无需任何其他选项:
declaration.f90:14:13:
call test(a, b)
1
Warning: Rank mismatch in argument ‘es’ at (1) (scalar and rank-2) [-Wargument-mismatch]
英特尔将需要警告标志
ifort -warn interfaces declaration.f90
declaration.f90(14): error #6637: When a dummy argument is a function, the corresponding actual argument must also be a function. [A]
call test(a, b)
-------------^
compilation aborted for declaration.f90 (code 1)
“但是链接时,考虑到缺少的符号es,没有错误!”
不应该有es
是伪参数的名称,而不是要传递到那里的实际过程的名称。实际上,在大多数实现中,代码会试图将变量指针作为函数地址调用,这会导致某种错误。要么执行不可执行代码,要么执行无效指令,要么执行病毒代码,这些代码被入侵者小心地放在堆栈或堆的正确位置
“是否有编译器选项(ifort或gfortran)强制将声明的变量视为意图(inout),而不是过程调用?”
不,即使是这样,它也会破坏代码语义,这是一件坏事(TM)。任何人在其他地方使用该代码,或者没有该选项,都将受到惩罚。尤其是它可能会造成危险的代码漏洞,这是不允许这样做的明显原因
最好明确地说,尽管我相信您已经意识到这一点,并且只需要一个诊断工具来警告您: 数组的正确声明涉及其维度,如
double precision es(1,*)
还要注意,编译器在调用过程时能够检查类似的错误。Gfortran将发现调用代码何时位于同一文件中,有时甚至是Intel(当启用了
-warn interfaces
时)。启用链接时间优化也有助于找到它。当然,现代Fortran应该使用模块
考虑:
subroutine test (es, f)
!
implicit none
!
double precision es
double precision f
f=es(1,2)
!
return
end
double precision a(2,1), b
call test(a, b)
end
由于调用位于同一文件中,gfortran将自动识别问题,无需任何其他选项:
declaration.f90:14:13:
call test(a, b)
1
Warning: Rank mismatch in argument ‘es’ at (1) (scalar and rank-2) [-Wargument-mismatch]
英特尔将需要警告标志
ifort -warn interfaces declaration.f90
declaration.f90(14): error #6637: When a dummy argument is a function, the corresponding actual argument must also be a function. [A]
call test(a, b)
-------------^
compilation aborted for declaration.f90 (code 1)
很快,但是-Wimplicit接口可能会在gfortran中有所帮助。但在老式代码中,您可能会被来自其他例程的信息淹没。最好的解决办法是为你的快速回答提供一个有意的答案。你知道英特尔fortran的-Wimplicit接口有什么等价物吗?@PilouPili-Wimplicit接口可能会给你带来如此多的点击,以至于你无法在其中找到一个奇怪的。你应该了解它的作用。它不符合您在问题中的要求,它将为您的程序中的每个Fortran 77样式调用提供警告。可能是几百,也可能是几千。我建议您使用编译器提供的错误检查选项。请看我的答案。对于英特尔来说,启用所有警告可能是
-warn interfaces
或只是-warn
。不过,在gfortran中,-Wimplicit接口可能会有所帮助。但在老式代码中,您可能会被来自其他例程的信息淹没。最好的解决办法是为你的快速回答提供一个有意的答案。你知道英特尔fortran的-Wimplicit接口有什么等价物吗?@PilouPili-Wimplicit接口可能会给你带来如此多的点击,以至于你无法在其中找到一个奇怪的。你应该了解它的作用。它不符合你的要求