2

我有一些看起来像这样的 fortran 代码:

 subroutine foo(mx,my,mz)
    real pts(3,mx,my,mz)
 end

数组 pts 从未在子例程中实际使用过——我只是在重构代码时忘记删除它。现在,由于 fortran 没有堆栈与堆的概念,这取决于编译器在哪里分配 pts - 这是 gfortran 中数组大小的函数,但我无法弄清楚波特兰组编译器如何处理这个。

是否可以判断 pts 是否分配在堆栈、堆上,或者是否完全优化(可能应该如此)?是否有可能有一个 stackoverflow 并且不知道它(即没有运行时错误)?我的直觉是,应该可以通过查看编译器生成的程序集来判断,但我不知道我会在那里看什么。

4

2 回答 2

6

最简单的方法是查看编译器在编译时提供的汇编代码-S或使用调试器查找符号。如果数组是在堆上分配的,很可能会调用分配函数:

  • gfortran插入调用malloc
  • ifort默认分配堆栈上的所有数组。如果您启用自动堆数组,-heap-arrays <size>它将生成for_alloc对堆分配的调用
  • PGI编译器生成调用,pgf90_auto_alloc但我没有使用此编译器及其分配数组的方式的经验

顺便说一句,即使使用默认优化级别,gfortran也会在未引用数组时删除该数组。我猜其他编译器也会这样做,但我不会打赌。

于 2012-05-23T20:11:16.230 回答
3

我认为这是一个高度特定于编译器的问题,从某种意义上说,与死代码消除相关的行为并不普遍,不仅是编译器特定的,而且是特定于案例的。启用优化的现代编译器肯定会消除所有无法访问的代码,或者在程序状态方面没有实现任何目标的代码。未使用的变量和数组根本不会出现在最终的可执行文件中。

正如您所提到的,最好的办法是查看已编译二进制文件的汇编代码,看看它做了什么。

于 2012-05-23T19:41:36.963 回答