Fortran控制字符(换行控制)在编译器中是否仍然实现?

9
科学家和工程师的Fortran 95/2003一书中,非常重要的一点是要认识到格式语句中的第一列保留用于控制字符。我也在互联网上看到过控制字符被称为换行控制。
为了避免混淆,我将“1、空格(即\s)、0和+”这些字符称为控制字符,当它们出现在第一个列(字符)的FORMAT语句中时,会对输出的垂直间距产生影响。
此外,请参考这个纯文本网页,完全使用等宽字体编写:Fortran换行控制(因为没有什么比等宽字体的散文更能表达准确性和古老感)。我发现这个页面和其他类似的页面并不太清晰。
根据科学家和工程师的Fortran 95/2003,忘记第一列是保留的换行控制符可能会导致可怕的意外输出。引用戴夫·巴里的话,输入错误字符,核导弹就会朝挪威发射。
然而,当我试图遵守这个严厉的警告时,我发现gfortran不知道我在说什么。
让我用一些示例代码来说明我的观点。 我正在尝试打印出Pi的值:
PROGRAM test_format
IMPLICIT NONE

REAL :: PI = 2 * ACOS(0.0)

WRITE (*, 100) PI
WRITE (*, 200) PI
WRITE (*, 300) PI
100 FORMAT ('1', "New page: ", F11.9)
200 FORMAT (' ', "Single Space: ", F11.9)
300 FORMAT ('0', "Double Space: ", F11.9)
END PROGRAM test_format

这是输出:

1New page: 3.141592741
Single Space: 3.141592741
0Double Space: 3.141592741

“1”和“0”并非笔误。看起来gfortran完全忽略了控制字符列。
我的问题是:
标准兼容的编译器是否仍然实现控制字符,还是gfortran不符合标准?
为了清晰起见,这是我的gfortran -v输出: 使用内置规范。 目标: powerpc-apple-darwin9 配置为: ../gcc-4.4.0/configure --prefix=/sw --prefix=/sw/lib/gcc4.4 --mandir=/sw/share/man --infodir=/sw/share/info --enable-languages=c,c++,fortran,objc,java --with-gmp=/sw --with-libiconv-prefix=/sw --with-ppl=/sw --with-cloog=/sw --with-system-zlib --x-includes=/usr/X11R6/include --x-libraries=/usr/X11R6/lib --disable-libjava-multilib --build=powerpc-apple-darwin9 --host=powerpc-apple-darwin9 --target=powerpc-apple-darwin9 线程模型: posix gcc版本4.4.0(GCC)

向您的ibiblio作者致以一些赞誉。他们的文档包含大量以纯文本格式排版的表格。选择等宽字体将是一个更糟糕的选择。并非每个人都能拥有标记源文件! - Pekka
5个回答

11

过去忽略第一列的用法可能会导致线打印机出现不良反应,例如页面弹出 -- 但是你最后一次看到线打印机是什么时候?否则,它是输出设备、编译器和操作系统相关的。《Fortran 95/2003 for Scientists and Engineers》的建议在15年或20年前是很好的,随着终端、后置脚本和其他现代打印机的出现,第一列不再特殊。我不再特别注意第一列,也没有遇到麻烦。

Fortran 2003标准将字符控制列定为已删除,这在Fortran语言标准中很少见。请参见“Fortran 95/2003 explained”第359页或“Fortran 2003 Handbook”的第326页。也许使用gfortran选择-std=f2003或-std=f2008可以确保第一列不被用作字符控制,以便完全避免“坏事”的发生。


2
+1:我很久以前就不喜欢查普曼的书,而且这仍然是我不喜欢他的原因之一。 - High Performance Mark

2
常见的打印机硬件可以根据第一列的内容执行特殊操作。请注意,行式打印机没有移动前后的打印头 - 它们有一个链或者鼓和132个锤子,每个锤子与缓冲区中的一个字节相关联。当锤子前面的字符与缓冲区中的字符匹配时,锤子将被激活,并且缓冲区的那个字节将被清空。当整个缓冲区都被清空时,打印机会加载下一行。
打印机没有回车、换行或分页控制字符的概念。相反,它们使用缓冲区的第一个字符来指示在打印每行之前纸张应该做什么(如果需要的话)。某些代码将按固定量推进纸张;其他代码将选择纸带读取器上的8列中的一列,并使打印纸和纸带一起向前推进,直到在适当的列上发现一个孔。传统上,纸带将是与打印页面长度相同的一个循环,第1列将有一个单独的孔; 纸张将被对齐,使得第1列的孔出现在每个页面上打印开始的位置。我曾经读过一个商店使用双倍长度的类型,并且第7列和第8列与风琴式纸张的内向和外向穿孔对齐。很棒的技巧 - 我想知道它有多常见。
无论如何,回车控制字符可能是一种与语言强烈相关的约定,但它们是硬件特性而不是语言特性。实际上,“1”将上移到页面顶部并没有特别的保证,除了大多数商店都恰好设置了它们的回车控制纸带。

1

我相信Fortran 95是最后一个在打印输出的第1列中指定字符特殊含义的版本。


在我的gfortran手册中,语法是-std=f95,但我仍然要感谢你的建议。然而,尝试这个并没有改变结果。 - EMiller
@Jerry_Coffin,我也看到了这一点,控制字符在Fortran 95之后就消失了。但是我认为为了向后兼容,第一个字符不会对输出产生影响,而只是被字面打印出来。 - EMiller
1
第一个字符必须与其他内容一起写入文件。当您告诉lpr命令使用f过滤器选项时,文件是唯一可以从中获取这些换行控制字符的地方。 - Windows programmer

1

为了输出到打印机,定义了回车控制字符。输出到其他类型的设备(例如穿孔卡片、纸带或那些新奇的磁性旋转圆形物体)则没有这些字符。如果您的输出是到磁盘文件,则gfortran正在做正确的事情。

编辑:gfortran确实在做正确的事情。如果您想要命令打印机驱动程序解释Fortran回车控制字符而不是按字面意义打印它们,请在lpr命令中使用f过滤器选项。例如,请参见http://www.computerhope.com/unix/ulpr.htm


虽然lpr-f标志曾经是标准,但它已从POSIX中删除。这可能表明FORTRAN换行控制确实是过去的事情。 - scruss

1
是的,Fortran编译器仍然支持Fortran回车控制,但通常默认情况下它被禁用。例如,在Intel Fortran中,需要使用非标准(但广泛实现的)CARRIAGECONTROL='FORTRAN'选项打开文件。查看gfortran是否有类似的选项。
话虽如此,我不建议使用这种约定编写新应用程序,因为它可能无法在所有输出设备上按照您希望的方式工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接