Compiler errors gfortran如何处理无法访问的代码? 让我们考虑一下FORTRAN 95代码(假设它包含在一个名为“代码> Me.F95/COD>”的文件中):
您可以注意到,Compiler errors gfortran如何处理无法访问的代码? 让我们考虑一下FORTRAN 95代码(假设它包含在一个名为“代码> Me.F95/COD>”的文件中):,compiler-errors,fortran,compiler-optimization,gfortran,Compiler Errors,Fortran,Compiler Optimization,Gfortran,您可以注意到,if(r32bit)的else部分无法访问。我运行了以下命令: % gfortran -O3 -Wunreachable-code -fdump-tree-optimized main.f95 查看是否gfortran找到了不可访问的部分并删除了无用的分支,但这会给出一个非常空的输出。在本例中,gfortran似乎没有删除代码中无法访问的部分 因此,我的问题是:是什么阻止了gfortran检测到这个,否则部分是无用的,并将其清除掉?我的编译器(gfortran 4.7和5.3-O
if(r32bit)
的else
部分无法访问。我运行了以下命令:
% gfortran -O3 -Wunreachable-code -fdump-tree-optimized main.f95
查看是否gfortran
找到了不可访问的部分并删除了无用的分支,但这会给出一个非常空的输出。在本例中,gfortran
似乎没有删除代码中无法访问的部分
因此,我的问题是:是什么阻止了gfortran
检测到这个,否则
部分是无用的,并将其清除掉?我的编译器(gfortran 4.7和5.3-O3-fdump tree-optimized
)是否消除了代码:
main (integer(kind=4) argc, character(kind=1) * * argv)
{
static integer(kind=4) options.1[9] = {68, 1023, 0, 0, 1, 1, 0, 0, 31};
<bb 2>:
_gfortran_set_args (argc_2(D), argv_3(D));
_gfortran_set_options (9, &options.1[0]);
print_state ();
return 0;
}
您不能期望优化修复无效的无法访问的代码。代码仍然无效,甚至无法访问
当我添加一些诊断时
if (r32bit) then
call r32_to_64bit(myReal, work8)
print *, '+'
else
work8 = myReal
print *, '-'
endif
它仍然被正确地消除:
test ()
{
struct __st_parameter_dt dt_parm.1;
<bb 2>:
print_state ();
dt_parm.1.common.filename = &"dead_elim.f90"[1]{lb: 1 sz: 1};
dt_parm.1.common.line = 34;
dt_parm.1.common.flags = 128;
dt_parm.1.common.unit = 6;
_gfortran_st_write (&dt_parm.1);
_gfortran_transfer_character_write (&dt_parm.1, &"+"[1]{lb: 1 sz: 1}, 1);
_gfortran_st_write_done (&dt_parm.1);
dt_parm.1 ={v} {CLOBBER};
return;
}
test()
{
结构参数dt参数1;
:
打印状态();
dt_parm.1.common.filename=&“dead_elim.f90”[1]{lb:1 sz:1};
dt_parm.1.common.line=34;
dt_parm.1.common.flags=128;
dt_parm.1.common.unit=6;
_gfortran_st_write(&dt_parm.1);
_gfortran_transfer_character_write(&dt_parm.1,&“+”[1]{lb:1 sz:1},1);
_gfortran_st_write_done(&dt_parm.1);
dt_parm.1={v}{CLOBBER};
返回;
}
程序确实会打印+
作为最后一次输出
在最终代码中没有条件,它被消除了
也许您希望
-fdump tree optimized
立即打印某些内容?它不会这样做,而是将优化后的代码写入文件。在我的例子中,它被命名为dead_elim.f90.191t.optimized
我的编译器(gfortran 4.7和5.3-O3-fdump tree optimized
)进行代码消除:
main (integer(kind=4) argc, character(kind=1) * * argv)
{
static integer(kind=4) options.1[9] = {68, 1023, 0, 0, 1, 1, 0, 0, 31};
<bb 2>:
_gfortran_set_args (argc_2(D), argv_3(D));
_gfortran_set_options (9, &options.1[0]);
print_state ();
return 0;
}
您不能期望优化修复无效的无法访问的代码。代码仍然无效,甚至无法访问
当我添加一些诊断时
if (r32bit) then
call r32_to_64bit(myReal, work8)
print *, '+'
else
work8 = myReal
print *, '-'
endif
它仍然被正确地消除:
test ()
{
struct __st_parameter_dt dt_parm.1;
<bb 2>:
print_state ();
dt_parm.1.common.filename = &"dead_elim.f90"[1]{lb: 1 sz: 1};
dt_parm.1.common.line = 34;
dt_parm.1.common.flags = 128;
dt_parm.1.common.unit = 6;
_gfortran_st_write (&dt_parm.1);
_gfortran_transfer_character_write (&dt_parm.1, &"+"[1]{lb: 1 sz: 1}, 1);
_gfortran_st_write_done (&dt_parm.1);
dt_parm.1 ={v} {CLOBBER};
return;
}
test()
{
结构参数dt参数1;
:
打印状态();
dt_parm.1.common.filename=&“dead_elim.f90”[1]{lb:1 sz:1};
dt_parm.1.common.line=34;
dt_parm.1.common.flags=128;
dt_parm.1.common.unit=6;
_gfortran_st_write(&dt_parm.1);
_gfortran_transfer_character_write(&dt_parm.1,&“+”[1]{lb:1 sz:1},1);
_gfortran_st_write_done(&dt_parm.1);
dt_parm.1={v}{CLOBBER};
返回;
}
程序确实会打印+
作为最后一次输出
在最终代码中没有条件,它被消除了
也许您希望
-fdump tree optimized
立即打印某些内容?它不会这样做,而是将优化后的代码写入文件。在我的例子中,它被命名为dead_elim.f90.191t.optimized
@Adrien我不相信你的代码是“不可访问的”。它只是错了,因为正如错误所述,你的real myReal
实际上是64位机器上的real(8)
。如果出现分支,编译器不能(也不应该)基于“无用”更改错误代码。我想你可以很容易地想象,如果(r32bit)使调用确实无法访问,那么这可能会彻底摧毁为现代用途重新编译的遗留代码库。@NoseKnowsAll条件。由于上述条件,如果myReal属于real(8)
,则无法调用它。我不是要求编译器更正错误的调用,而是不要在一个永远不会执行的调用上引发错误。@francescalus这是有道理的。它解释了使用-fdefault-real-8
选项编译失败的原因。但它并没有解释为什么在没有这个选项的情况下编译时不会执行消除操作(在这种情况下,代码是有效的)。代码是无效的。=>编译器引发了一个错误。句号。你还想听什么?没有理由认为消除会改变任何事情。@VladimirF如果没有使用-fdefault-real-8
,代码怎么会无效?@Adrien我不相信你的代码是“无法访问的”。这只是错了,因为错误表明,你的real myReal
实际上是64位机器上的real(8)
。如果出现分支,编译器不能(也不应该)基于“无用”更改错误代码。我想你可以很容易地想象,如果(r32bit)
使调用确实无法访问,那么这可能会彻底摧毁为现代用途重新编译的遗留代码库。@NoseKnowsAll条件。由于上述条件,如果myReal属于real(8)
,则无法调用它。我不是要求编译器更正错误的调用,而是不要在一个永远不会执行的调用上引发错误。@francescalus这是有道理的。它解释了使用-fdefault-real-8
选项编译失败的原因。但它并没有解释为什么在没有这个选项的情况下编译时不会执行消除操作(在这种情况下,代码是有效的)。代码是无效的。=>编译器引发了一个错误。句号。你还想听什么?没有理由认为消除会改变任何事情。@VladimirF如果不使用-fdefault-real-8
,代码怎么会无效?我现在觉得自己像个白痴。我认为-fdump tree optimized
将其输出打印为标准输出,而不是文件。。。我有和你一样的结果。谢谢。我现在觉得自己像个白痴。我认为-fdump tree optimized
将其输出打印为标准输出,而不是文件。。。我有和你一样的结果。谢谢