在实现字符串实用程序功能时,我遇到了一些我认为可能不安全的字符指针表达式。我用谷歌搜索,搜索了SO,阅读了我的Fortran 95语言指南(Gehrke 1996)以及Google书籍中展示的各种摘录。但是,我找不到任何讨论这种特殊用法的消息来源。
ifort和gfortran都会在没有警告的情况下编译以下程序:
PROGRAM test_pointer
IMPLICIT NONE
CHARACTER(LEN=100), TARGET :: string = "A string variable"
CHARACTER(LEN=0), TARGET :: empty = ""
CHARACTER(LEN=:), POINTER :: ptr
ptr => NULL()
IF(ptr == "") PRINT *, 'Nullified pointer is equal to ""'
ptr => string(-2:-3)
IF(ptr == "") PRINT *, 'ptr equals "", but the (empty) sub string was out of bounds.'
ptr => empty(1:0)
IF(ptr == "") PRINT *, 'ptr equals "", it was not possible to specify subarray within bonds'
END PROGRAM
该计划的输出是:
Nullified pointer is equal to ""
ptr equals "", but the (empty) sub string was out of bounds.
ptr equals "", it was not possible to specify subarray within bonds
显然,指针的评估对编译器有意义,结果就是你所期望的。有人可以解释为什么上面的代码没有导致至少一个分段错误?标准是否真的允许越界子串?如何使用无效字符指针?
编辑阅读完Vladimir F的回答后,我意识到我忘了激活运行时检查。无效指针实际上会触发运行时错误。
答案 0 :(得分:5)
为什么他们不会导致段错误?取消引用无效指针不符合标准(在C术语中,它是未定义的行为)。该标准没有说明不合格的程序应该做什么。该标准仅适用于符合它的程序!对于不合格的程序,任何事情都可能发生!
我得到了这个(sunf90):
****** FORTRAN RUN-TIME SYSTEM ******
Attempting to use an unassociated POINTER 'PTR'
Location: line 8 column 6 of 'charptr.f90'
Aborted
和另一个编译器(ifort):
forrtl: severe (408): fort: (7): Attempt to use pointer PTR when it is not associated with a target
Image PC Routine Line Source
a.out 0000000000402EB8 Unknown Unknown Unknown
a.out 0000000000402DE6 Unknown Unknown Unknown
libc.so.6 00007FA0AE123A15 Unknown Unknown Unknown
a.out 0000000000402CD9 Unknown Unknown Unknown
对于其他两个访问,你没有访问任何东西,你正在创建一个长度为0的子字符串,不需要访问字符变量,结果只是一个空字符串。
具体来说,Fortran标准(F2008:6.4.1.3)说明了创建子字符串:
起点和终点都在 范围1,2,...,n 除非起点超过结束 point ,在这种情况下,子字符串的长度为零。
由于这个原因,第一部分不符合标准,但其他部分则是。