在C和C ++中,有许多操作会导致未定义的行为,即允许编译器执行所需操作的情况。示例包括在取消分配变量后使用变量,两次取消分配变量以及取消引用空指针。
Fortran是否也具有未定义的行为?我看了一份规范草案,但未能在其中找到任何东西。例如,在释放变量之后使用变量肯定会导致程序崩溃,还是它会默默地做错事?
Vla*_*r F 10
是的,它有。只是被称为不同。您可以做很多事情,并使您的代码不符合标准,而无需处理器(编译器)诊断此类不符合项(当然,必须诊断出许多偏差)。通常情况将类似于C的未定义行为(例如,超出范围访问数组,有符号整数溢出等)。我们只是说该代码不符合标准,这意味着该标准并未规定此类代码的结果。此类代码未涵盖在标准中,因此,如果某些编译器(处理器)对它进行编译并且您运行了它,则可能会导致任何后果。
这与处理器相关的行为不同,后者是标准的,仅取决于实现。
只需在StackOverflow上搜索即可为您提供大量示例。像是将同一实体传递给具有不同意图的参数的未定义行为吗? Fortran和MPI_Reduce如何处理整数溢出?
fra*_*lus 10
Fortran标准确实接受与C和C ++的“未定义行为”概念类似的概念。人们经常将支持损坏的Fortran代码的措辞称为“编译器现在可能开始第三次世界大战”或类似。
Fortran语言规范具有两种一致性概念(请参阅Fortran 2018,4.2)。最主要的是程序必须具有什么样的外观才能被视为Fortran程序。第二个是处理器必须响应提交的程序单元才能被视为Fortran处理器。
如果要求兼容的Fortran处理器处理不是Fortran程序的内容,则标准很少说明必须发生的情况。有一些诊断必须提供,但通常没有。
在“在释放变量后使用变量”的情况下,尝试执行此操作违反了定义Fortran 程序的语言标准部分。然后,编译器可以在不违反Fortran标准的情况下“发动第三次世界大战”,因为Fortran标准没有说它不能(或必须做其他事情)。
现在,我们如何看待Fortran标准文档,并确定非完全Fortran程序是否具有特定的必需作用?4.2中的文本提到了编译器必须具有“在提交的程序单元中检测和报告使用情况的能力”的许多情况。如果您提出的程序没有成功,那么您属于“未定义”领域。
在这种情况下,主要必须报告程序错误的主要时间
在提交的程序单元中使用编号语法规则或约束所不允许的形式或关系
让我们任意考虑Fortran 2018、15.5.1C1523(R1520)过程引用的语法。我们看到类似“ R1520”的内容:
R1520 功能参考是过程指示符([ actual-arg-spec-list ])
和“ C1523”:
C1523(R1520)程序指示符应指定一个功能。
在我们列出以下内容之前:
该数据REF的过程的指示符不得未分配的分配变量或不相关联的指针。
在这种情况下,规则R1520,编号为约束C1523(适用于此规则)和以下文本给出了对Fortran程序的约束。如果您提交的程序不符合要求,则说明它不是符合标准的Fortran程序。
要求处理这种不合格程序的编译器必须能够检测到该不合格程序(基于以上内容),该程序不符合R1520或C1523。编译器不必抱怨或检测到未编号文本的冲突。可以假定所提供的任何程序都不会违反这种未编号的限制。
我在此引用的这个(偶然地)是一个禁止使用先前释放的变量错误地禁止程序的示例。
如果处理器以“编译然后运行”的方式运行,则编号的规则/约束通常是可以在“编译时”进行评估的规则/约束。