这种字符串指针的使用安全吗?

Ø. *_*sen 4 standards fortran pointers

在实现字符串实用程序功能时,我遇到了一些我认为可能不安全的字符指针表达式.我用谷歌搜索,搜索了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
Run Code Online (Sandbox Code Playgroud)

该计划的输出是:

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
Run Code Online (Sandbox Code Playgroud)

显然,指针的评估对编译器有意义,结果就是你所期望的.有人可以解释为什么上面的代码没有导致至少一个分段错误?标准是否真的允许越界子串?使用无效字符指针怎么样?

编辑:读完弗拉基米尔F的答案后,我意识到我忘了激活运行时检查.无效指针实际上会触发运行时错误.

Vla*_*r F 5

为什么他们不会导致段错误?取消引用无效指针不符合标准(在C术语中,它是未定义的行为).该标准没有说明不合格的程序应该做什么.该标准仅适用于符合它的程序!对于不合格的程序,任何事情都可能发生!

我明白了(sunf90):

 ******  FORTRAN RUN-TIME SYSTEM  ******
 Attempting to use an unassociated POINTER 'PTR'
 Location:  line 8 column 6 of 'charptr.f90'
Aborted
Run Code Online (Sandbox Code Playgroud)

和另一个编译器(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
Run Code Online (Sandbox Code Playgroud)

对于其他两个访问,您没有访问任何内容,您正在创建长度为0的子字符串,不需要访问字符变量,结果只是一个空字符串.

具体来说,Fortran标准(F2008:6.4.1.3)说明了创建子字符串:

除非起点超过终点,否则起点和终点都应在1,2,...,n范围内,在这种情况下,子串的长度为零.


因此,第一部分不是标准符合,而是其他部分.