【问题标题】:fortran: Error: Type mismatch between actual argument at (1) and actual argument at (2) (INTEGER(8)/INTEGER(2))fortran:错误:(1) 处的实际参数和 (2) 处的实际参数之间的类型不匹配 (INTEGER(8)/INTEGER(2))
【发布时间】:2021-10-23 09:20:34
【问题描述】:

我是 Fortran 的初学者,正在运行由 Fortran 编写的模型。当我尝试编译它时,我收到一条错误消息,例如:

libtool: link: (cd ".libs" && rm -f "libgrib_api_f77.so" && ln -s "libgrib_api_f77.so.1.0.0" "libgrib_api_f77.so")
libtool: link: ar cru .libs/libgrib_api_f77.a  grib_fortran.o grib_f77.o
libtool: link: ranlib .libs/libgrib_api_f77.a
libtool: link: ( cd ".libs" && rm -f "libgrib_api_f77.la" && ln -s "../libgrib_api_f77.la" "libgrib_api_f77.la" )
gfortran   -c -o same_int_long.o same_int_long.f90
same_int_long.f90:23:18:
 
   17 |   call check_long(x2(1),x2(2),ret)
      |                  2
......
   23 |   call check_long(x4(1),x4(2),ret)
      |                  1
Error: Type mismatch between actual argument at (1) and actual argument at (2) (INTEGER(4)/INTEGER(2)).
same_int_long.f90:29:18:
 
   17 |   call check_long(x2(1),x2(2),ret)
      |                  2
......
   29 |   call check_long(x8(1),x8(2),ret)
      |                  1
Error: Type mismatch between actual argument at (1) and actual argument at (2) (INTEGER(8)/INTEGER(2)).
same_int_long.f90:51:17:
 
   45 |   call check_int(x2(1),x2(2),ret)
      |                 2
......
   51 |   call check_int(x4(1),x4(2),ret)
      |                 1
Error: Type mismatch between actual argument at (1) and actual argument at (2) (INTEGER(4)/INTEGER(2)).
same_int_long.f90:57:17:
 
   45 |   call check_int(x2(1),x2(2),ret)
      |                 2
......
   57 |   call check_int(x8(1),x8(2),ret)
      |                 1
Error: Type mismatch between actual argument at (1) and actual argument at (2) (INTEGER(8)/INTEGER(2)).
make[2]: *** [Makefile:546: same_int_long.o] Error 1
make[2]: Leaving directory '/gpfs/home3/eccei339/snellius_surfex/open_SURFEX_V8_1/src/LIB/grib_api-1.17.0-Source/fortran'
make[1]: *** [Makefile:604: all-recursive] Error 1
make[1]: Leaving directory '/gpfs/home3/eccei339/snellius_surfex/open_SURFEX_V8_1/src/LIB/grib_api-1.17.0-Source'
make: *** [Makefile:398: /home/eccei339/snellius_surfex/open_SURFEX_V8_1/src/LIB/grib_api-1.17.0-Source-LXgfortran/include/grib_api.mod] Error 2

我所做的基本上是按照模型的安装:

第一步

(base) [eccei339@int3 ~]$ mkdir snellius_surfex
(base) [eccei339@int3 ~]$ cp open_surfex_v8_1_20200107.tar-2.gz snellius_surfex/
(base) [eccei339@int3 ~]$ cd snellius_surfex/
(base) [eccei339@int3 snellius_surfex]$ tar zxvf open_surfex_v8_1_20200107.tar-2.gz

…(省略 tar zxvf 日志信息)

第 2 步:一些必要的环境变量

(base) [eccei339@int3 snellius_surfex]$ export VER_MPI="NOMPI"
(base) [eccei339@int3 snellius_surfex]$ export OMP_NUM_THREADS=1
(base) [eccei339@int3 snellius_surfex]$ module load 2021
(base) [eccei339@int3 snellius_surfex]$ module load GCC/10.3.0
(base) [eccei339@int3 snellius_surfex]$ ls
open_SURFEX_V8_1  open_surfex_v8_1_20200107.tar-2.gz

(这里我按照软件安装说明导出了一些必要的env var)

第 3 步:配置

(base) [eccei339@int3 snellius_surfex]$ cd open_SURFEX_V8_1/src/
(base) [eccei339@int3 src]$ ls
ASSIM      Makefile            Rules.bullXI15.mk    Rules.MCgfortran.mk  SURFEX
configure  Makefile.SURFEX.mk  Rules.bullXI16.mk    Rules.SX8.mk
FORC       OFFLIN              Rules.LXgfortran.mk  Rules.zgfortran.mk
include    Rules.AIX64.mk      Rules.LXifort.mk     Rules.zifort.mk
LIB        Rules.bgfortran.mk  Rules.LXpgi.mk       scripts
(base) [eccei339@int3 src]$ ./configure

(省略“configure”命令的长日志信息)

(base) [eccei339@int3 src]$ . ../conf/profile_surfex-LXgfortran-SFX-V8-1-1-NOMPI-OMP-O2-X0

(软件安装说明的必要步骤)

第 4 步:制作大师

(base) [eccei339@int3 src]$ make
find: ‘/home/eccei339/snellius_surfex/open_SURFEX_V8_1/src/dir_obj-LXgfortran-SFX-V8-1-1-NOMPI-OMP-O2-X0/MASTER’: No such file or directory
cd /home/eccei339/snellius_surfex/open_SURFEX_V8_1/src/LIB/grib_api-1.17.0-Source && LDFLAGS= FCFLAGS= CPPFLAGS="" \
 ./configure --disable-jpeg --prefix=/home/eccei339/snellius_surfex/open_SURFEX_V8_1/src/LIB/grib_api-1.17.0-Source-LXgfortran FC="gfortran" && \
 make -j 1 clean && \
 make -j 1 && \
 make -j 1 install && \
 make -j 1 clean
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking how to print strings... printf
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... no

(省略长日志信息,最后几行是本问题描述开头显示的错误消息。)

我上网查了一下,这可能是因为 GCC 10 比旧的 GCC 更严格(我去年用旧的 GCC 编译了这个模型并做了,但是这次失败了,因为我们的服务器转移到了一个新的系统,因此 GCC 从旧版本升级到新版本)。来自 Google 的一些信息说我可以添加如下内容:

export FCFLAGS="-w -fallow-argument-mismatch -O2"
export FFLAGS="-w -fallow-argument-mismatch -O2"

但我在步骤 2 中尝试了导出一些基本环境变量,但它仍然无法正常工作。所以我想知道有没有人可以帮助我?非常感谢!

更新:http://distfiles.macports.org/grib_api/grib_api-1.17.0-Source/fortran/same_int_long.f90源代码如下:

! Copyright 2005-2016 ECMWF.
!
! This software is licensed under the terms of the Apache Licence Version 2.0
! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
! 
! In applying this licence, ECMWF does not waive the privileges and immunities granted to it by
! virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.

integer function kind_of_long()
  integer(2), dimension(2) :: x2 = (/1, 2/)
  integer(4), dimension(2) :: x4 = (/1, 2/)
  integer(8), dimension(2) :: x8 = (/1, 2/)
  character(len=1) :: ret

  kind_of_long=-1

  call check_long(x2(1),x2(2),ret)
  if (ret == 't') then
   kind_of_long=2
   return
  endif

  call check_long(x4(1),x4(2),ret)
  if (ret == 't') then
   kind_of_long=4
   return
  endif

  call check_long(x8(1),x8(2),ret)
  if (ret == 't') then
   kind_of_long=8
   return
  endif

end function kind_of_long

integer function kind_of_int()
  integer(2), dimension(2) :: x2 = (/1, 2/)
  integer(4), dimension(2) :: x4 = (/1, 2/)
  integer(8), dimension(2) :: x8 = (/1, 2/)
  character(len=1) :: ret

  kind_of_int=-1

  call check_int(x2(1),x2(2),ret)
  if (ret == 't') then
   kind_of_int=2
   return
  endif

  call check_int(x4(1),x4(2),ret)
  if (ret == 't') then
   kind_of_int=4
   return
  endif

  call check_int(x8(1),x8(2),ret)
  if (ret == 't') then
   kind_of_int=8
   return
  endif

end function kind_of_int

program same_int_long
  integer ki,kl

  ki=kind_of_int()
  kl=kind_of_long()
  if (ki /= kl) then
    write (*,'(i1)') 0
  else
    write (*,'(i1)') 1
  endif
end program same_int_long


这里是make的完整日志信息:https://drive.google.com/file/d/14rkj2ay39Rv84QBL6UDiSdlIAfhuEt_z/view?usp=sharing

【问题讨论】:

  • 为了能够说出任何我们需要查看可以运行的完整代码 (MWE) 的内容,至少我们需要 x..check_long 的声明/定义
  • 嗨@Albert,感谢您的回复!但我认为这与x..check_long 无关...应该是因为不匹配错误...似乎较旧的GCC在编译它们时可以容忍代码中的这种不匹配,但是GCC 10不能...
  • 您必须出示代码。在传递参数时使用参数的声明和子例程内的声明。这不太可能是由于 GCC10 造成的,更有可能是声明中存在一些不可移植性。值得注意的是,如果您知道原因,就不会在这里寻求帮助,所以如果人们认为声明是必要的,这确实意味着它们很可能是需要的。
  • 嗨@VladimirF,感谢您的回复!查了一下日志信息,发现是gfortran -c -o same_int_long.o same_int_long.f90使用make编译master的时候报错了。而且我找不到这个 .f90 文件在哪里...我只知道./configure 的日志信息,它在grib_api-1.17.0-Source/fortran/same_int_long.f90...
  • @XuShan 很可能是关于x..check_long,旧的编译器在编译过程中对不同大小类型不同长度的变量更加宽松,导致运行过程中出现未定义的行为时间和可能的错误。所以显示你的代码。

标签: linux makefile fortran gnu-make gfortran


【解决方案1】:

这对我来说是一个 MPI fortran 代码。原因是 gcc 开发人员决定什么应该是“好的接口”see here。 我的情况有两种解决方案:

  • 使用选项 -fallow-argument-mismatch 告诉 gfortran 忽略此问题。
  • 使用现代 fortran 界面(use mpi 而不是 include mpif.h) 我选择了后者。

【讨论】:

  • 我真的很想知道 Deutsches Alpenverein 和他们的高山攀登与 Fortran 和 MPI 有什么关系...
  • 这似乎是相同的错误消息,但潜在的问题有所不同。不过,了解一下很有用。
  • 我不会说这是关于开发人员对子程序接口的意见。相反,这是关于他们对遵守 Fortran 规则的看法。一般的 Fortran 编译器,特别是 gfortran 传统上默认情况下对此非常松懈,但最近的 gfortran 默认情况下对参数/实际参数类型匹配更加严格。
【解决方案2】:

您作为 INTEGER 实例化的内容是通过另一个(变量或声明)整数不同的“字节”内存存储大小分配其值。 例如在其他语言中,int 是 4 个字节,long 是 8 个字节。 (注)Fortran 也有类似 C/C++ 的指针 https://docs.oracle.com/cd/E19957-01/805-4939/6j4m0vna5/index.html 注意:您没有显示有问题的代码,在源文件 same_int_long.f90 的第 29 行 char 18 附近??

【讨论】:

  • 嗨@Samuel Marchant,感谢您的回答!是的,代码应该在源文件grib_api-1.17.0-Source/fortran/same_int_long.f90 中(我是从./configure 的日志信息中找到的)。但是我找不到这个源文件在哪里...
  • 但是无论如何,我去年确实用完全相同的文件编译了这个模型...我不知道为什么这次它不起作用...模型的来源与我去年用的那个……
  • 注意到另一个 (same_int_long.f90:57:17:) 这是您去年使用的代码的实际版本还是不同的版本?
  • 是的,代码的实际版本。
  • 编译器?同一个版本?我知道它们对于每个品牌来说都是非常不同的,不管是在同一年。例如有些人 f90 编译器,完全相同的编译器(相同的平台?)?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-11
  • 2012-08-29
  • 2020-02-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多