From c0eef9324499009484079ca53eb286c762caa862 Mon Sep 17 00:00:00 2001 From: Euler-37 <64597797+Euler-37@users.noreply.github.com> Date: Sun, 31 Mar 2024 20:03:03 +0800 Subject: [PATCH] Update ch08-01-memory.md --- src/ch08-01-memory.md | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/ch08-01-memory.md b/src/ch08-01-memory.md index f610a30..2230506 100644 --- a/src/ch08-01-memory.md +++ b/src/ch08-01-memory.md @@ -2,12 +2,24 @@ 现代Fortran在不引入指针的情况下,是一个内存安全的语言(但是Fortran编译器可能不安全),但是还有一个简单的情况是无法处理的,即变量的别名。 -在Fortran中,对于处于同一个作用域内的变量,一般不存在别名,但是Fortran中假设子程序的虚参也是不含别名的,这带来了一定的危险 +在Fortran中,对于处于同一个作用域内的变量,一般不存在别名(不引入指针的情况下),但是Fortran的标准中规定子程序的虚参是不含别名的,但是在实际的代码编写过程中不一定能保证这件事。 一个典型的内存别名的例子是 ``` fortran +module test_mod + implicit none +contains + subroutine test(a,b) + integer,intent(in)::a + integer,intent(inout)::b + b=a+b + b=b+b + end subroutine test +end module test_mod + program main + use test_mod implicit none integer::a,b a=2 @@ -17,16 +29,9 @@ program main b=0 call test(a,b) write(*,*)b -contains - subroutine test(a,b) - integer,intent(in)::a - integer,intent(inout)::b - b=a+b - b=b+b - end subroutine test end program main ``` 此时,第一个例子`test`中传入的参数均为`a`,那么在`test`中`a`即使`intent(in)`属性又是`intent(inout)`属性。而在`test`的作用域中,变量`a`和`b`实际上表示的是同一块内存。这为我们实际的代码调试检查 -带来了一定的难度,所以在实际的代码编写中,一定要杜绝这类代码。 +带来了一定的难度,所以在实际的代码编写中,尽量要杜绝这类代码。 同时,在使用我们前一节提到的`associate`的时候,要注意同时操作两个别名对数据进行处理的情况。