Fortran 格式是在编译时还是执行时完成的?
Are Fortran FORMATs done during compile time or execution time?
FORTRAN 语法的一部分是格式,例如:
WRITE(*,10)'this is a string', 'this is a second string', 'this is a third string'
10 FORMAT(1x,a10,1x,a10,1x,a20)
我想知道代码格式化的时候,是编译时还是执行时?我怎么能测试这个?检查装配差异?
格式字符串通常在运行时进行解释。 经过所有这些编辑之后,它毕竟不是那么典型,请参阅史蒂夫的回答。答案描述了 gfortran,它甚至可能不太典型,但很重要且广泛使用。 特别是当格式字符串是字符变量(可以是任何东西)时,还有 FORMAT 语句。您通常只在运行时收到格式不正确的错误消息。例如:
WRITE(*,10) x
10 FORMAT(i0)
END
给予
> ./a.out
At line 8 of file format3.f90 (unit = 6, file = 'stdout')
Fortran runtime error: Expected INTEGER for item 1 in formatted transfer, got REAL
(i0)
^
你的情况:
gfortran -O3 format3.f90 -fdump-tree-optimized
给予
dt_parm.0.common.filename = &"format3.f90"[1]{lb: 1 sz: 1};
dt_parm.0.common.line = 1;
dt_parm.0.format = &"(1x,a10,1x,a10,1x,a20)"[1]{lb: 1 sz: 1};
dt_parm.0.format_len = 22;
dt_parm.0.common.flags = 4096;
dt_parm.0.common.unit = 6;
_gfortran_st_write (&dt_parm.0);
_gfortran_transfer_character_write (&dt_parm.0, &"this is a string"[1]{lb: 1 sz: 1}, 16);
_gfortran_transfer_character_write (&dt_parm.0, &"this is a second string"[1]{lb: 1 sz: 1}, 23);
_gfortran_transfer_character_write (&dt_parm.0, &"this is a third string"[1]{lb: 1 sz: 1}, 22);
_gfortran_st_write_done (&dt_parm.0);
dt_parm.0 ={v} {CLOBBER};
_gfortran_st_write (&dt_parm.0);
设置写入模式,包括格式字符串。
您可以注意到格式存储在一个字符变量中,如果需要可以在运行时进行解释,但实际上并没有在编译器生成的代码中使用。它可能在作为 libgfortran 运行时库的一部分的 _gfortran_transfer_character_write
中使用。
以上是针对 gfortran 的。可以想象很多东西实际上可以被优化和编译,但我不知道编译器会那样做。
如果你好奇的话,gfortran格式的解释代码在https://github.com/gcc-mirror/gcc/blob/trunk/libgfortran/io/format.c
我工作过的编译器总是在编译时将格式转换为内部表示,而不是存储在字符变量中的格式。 运行 时间系统仍然必须具有在 运行 时间进行 "compile" 格式化的能力,但编译器可以检查错误。输出的实际格式化总是发生在 运行 时间。
FORTRAN 语法的一部分是格式,例如:
WRITE(*,10)'this is a string', 'this is a second string', 'this is a third string'
10 FORMAT(1x,a10,1x,a10,1x,a20)
我想知道代码格式化的时候,是编译时还是执行时?我怎么能测试这个?检查装配差异?
格式字符串通常在运行时进行解释。 经过所有这些编辑之后,它毕竟不是那么典型,请参阅史蒂夫的回答。答案描述了 gfortran,它甚至可能不太典型,但很重要且广泛使用。 特别是当格式字符串是字符变量(可以是任何东西)时,还有 FORMAT 语句。您通常只在运行时收到格式不正确的错误消息。例如:
WRITE(*,10) x
10 FORMAT(i0)
END
给予
> ./a.out
At line 8 of file format3.f90 (unit = 6, file = 'stdout')
Fortran runtime error: Expected INTEGER for item 1 in formatted transfer, got REAL
(i0)
^
你的情况:
gfortran -O3 format3.f90 -fdump-tree-optimized
给予
dt_parm.0.common.filename = &"format3.f90"[1]{lb: 1 sz: 1};
dt_parm.0.common.line = 1;
dt_parm.0.format = &"(1x,a10,1x,a10,1x,a20)"[1]{lb: 1 sz: 1};
dt_parm.0.format_len = 22;
dt_parm.0.common.flags = 4096;
dt_parm.0.common.unit = 6;
_gfortran_st_write (&dt_parm.0);
_gfortran_transfer_character_write (&dt_parm.0, &"this is a string"[1]{lb: 1 sz: 1}, 16);
_gfortran_transfer_character_write (&dt_parm.0, &"this is a second string"[1]{lb: 1 sz: 1}, 23);
_gfortran_transfer_character_write (&dt_parm.0, &"this is a third string"[1]{lb: 1 sz: 1}, 22);
_gfortran_st_write_done (&dt_parm.0);
dt_parm.0 ={v} {CLOBBER};
_gfortran_st_write (&dt_parm.0);
设置写入模式,包括格式字符串。
您可以注意到格式存储在一个字符变量中,如果需要可以在运行时进行解释,但实际上并没有在编译器生成的代码中使用。它可能在作为 libgfortran 运行时库的一部分的 _gfortran_transfer_character_write
中使用。
以上是针对 gfortran 的。可以想象很多东西实际上可以被优化和编译,但我不知道编译器会那样做。
如果你好奇的话,gfortran格式的解释代码在https://github.com/gcc-mirror/gcc/blob/trunk/libgfortran/io/format.c
我工作过的编译器总是在编译时将格式转换为内部表示,而不是存储在字符变量中的格式。 运行 时间系统仍然必须具有在 运行 时间进行 "compile" 格式化的能力,但编译器可以检查错误。输出的实际格式化总是发生在 运行 时间。