Fortran77代码编译call itime(now)等报错问题排查
编译错误根因分析
- 主程序第8行报错
attempt to give DATA in type-declaration
严格遵循Fortran77标准的编译器不支持在类型声明语句中直接通过DATA语法给变量赋初值,这种写法是Oracle(原Sun)Fortran提供的非标准厂商扩展,之前测试用的fort77、f77、gfortran默认遵循标准F77语法检查,会直接判定该写法非法。 call itime(now)语句触发error #6404类型错误
该错误由两个问题共同导致:itime是Oracle Fortran专属的内置时间子例程,不属于F77标准库范围,开源Fortran编译器没有内置该实现,会默认将其识别为未定义的外部过程;- 代码中没有提前声明
now变量的类型,当编译器开启强制显式类型检查时,会直接抛出变量无定义的错误。
- 局部变量k、rand未使用警告
属于遗留代码常见的冗余声明问题,一般是代码迭代过程中残留的无用变量定义,不会阻断编译流程,仅做提示。
可行修复方案
- 修复DATA内嵌类型声明错误
将类型声明和DATA初始化拆分为两条独立的标准F77语句即可兼容所有编译器,示例:! 原非标准写法(仅Oracle编译器支持) ! REAL a/1.0/, b/2.0/ ! 替换为标准写法 REAL a, b DATA a /1.0/, b /2.0/ - 修复itime相关类型错误
两种方案可按需选择:- 适配Oracle Fortran编译:在所有调用
itime的子例程(input、initialize)的变量声明段开头,补充INTEGER now(3)声明即可——Oracle Fortran的itime子例程要求传入长度为3的整型数组,按顺序返回当前的小时、分钟、秒数值。 - 适配gfortran等通用开源编译器:除了补充上述
now变量的声明外,将call itime(now)替换为通用编译器支持的date_and_time内置子例程实现相同逻辑,替换代码如下:! 注释掉原call itime(now)语句,替换为以下内容 CHARACTER(len=8) cur_time_str call date_and_time(TIME=cur_time_str) read(cur_time_str, '(I2,I2,I2)') now(1), now(2), now(3) ! 替换后now数组的返回值逻辑和原itime完全一致:now(1)为小时、now(2)为分钟、now(3)为秒
- 适配Oracle Fortran编译:在所有调用
- 处理未使用变量警告
不影响代码运行的前提下可直接忽略,也可以选择两种方式消除警告:- 直接删除或注释k、rand两个冗余变量的声明语句;
- 编译时添加对应参数跳过未使用变量检查,比如gfortran可添加
-Wno-unused-variable编译参数。
注意:该代码运行依赖同目录下的
inputnewrate.txt参数配置文件,编译通过后执行程序时需要保证工作目录下存在该文件,否则会触发文件读取报错。
内容的提问来源于stack exchange,提问作者krishnab
相关产品推荐
相关产品推荐

