向量函数的赋值是原子的吗? (无法理解错误)
Is the assigment of a vector function atomic? (Can't understand error)
我遇到了一个程序段错误,我知道出了点问题,因为我使用了一个未分配的参数,但我并不真正理解该错误的内部工作原理:
program MWE
implicit none
integer, allocatable :: b(:)
call S(b)
contains
subroutine S(a)
integer, intent(out) :: a(:)
a = F(10) !I was expecting the error here
! but in the assigment not inside
! the function call.
end subroutine
function F(n) result(v)
integer, intent(in) :: n
integer :: v(n)
print*, "Now comes the error"
v = 1 !here, in this assignment
print*, "We nevet get here"
end function
end program
我知道我正在将变量 a 声明为 allocatable,并且我知道我正在将它传递给子例程 S 而没有分配它。
但是我希望函数 F 可以正常工作,因为它被给定 N 并且因此它知道 v。我希望分段错误出现在完成 F 之后,但在将其输出分配给 a.
之前
鉴于我在函数 F 中得到错误,我误解了一些内部工作,但我不知道是什么。
这是执行输出:
Now comes the error
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0 0x7f1bff9f28b0 in ???
#1 0x7f1bff9f1ae3 in ???
#2 0x7f1bff66c83f in ???
at /build/glibc-vjB4T1/glibc-2.28/signal/../sysdeps/unix/sysv/linux/x86_64/sigaction.c:0
#3 0x562fc494c262 in ???
#4 0x562fc494c3d3 in ???
#5 0x562fc494c30b in ???
#6 0x562fc494c40c in ???
#7 0x7f1bff65909a in __libc_start_main
at ../csu/libc-start.c:308
#8 0x562fc494c0b9 in ???
#9 0xffffffffffffffff in ???
Segmentation fault
对于该函数调用,gfortran 将隐藏参数传递给函数,告诉函数应该将函数结果放在内存中的什么位置。该隐藏参数指定与子例程中的 a
伪参数关联的存储。该存储无效,因为尚未分配与 a
虚拟对象关联的实际参数,因此该函数尝试将其结果放入的存储无效,因此您会在函数内部看到访问冲突。
与赋值语句关联的操作隐含在让函数直接写入赋值左侧事物的存储中。
不同的编译器(或相同的编译器,对于具有不同特征的函数调用或赋值语句)将以不同的方式实现这一点 - 例如,函数可能写入调用代码设置然后复制的临时文件结束,或者可能在调用代码需要释放的函数内部分配缓冲区。
您可以通过检查程序集(将 -S 添加到命令行)或中间表示之一(例如 -fdump-tree-original)来检查 gfortran 编译器如何实现您的程序
我遇到了一个程序段错误,我知道出了点问题,因为我使用了一个未分配的参数,但我并不真正理解该错误的内部工作原理:
program MWE
implicit none
integer, allocatable :: b(:)
call S(b)
contains
subroutine S(a)
integer, intent(out) :: a(:)
a = F(10) !I was expecting the error here
! but in the assigment not inside
! the function call.
end subroutine
function F(n) result(v)
integer, intent(in) :: n
integer :: v(n)
print*, "Now comes the error"
v = 1 !here, in this assignment
print*, "We nevet get here"
end function
end program
我知道我正在将变量 a 声明为 allocatable,并且我知道我正在将它传递给子例程 S 而没有分配它。
但是我希望函数 F 可以正常工作,因为它被给定 N 并且因此它知道 v。我希望分段错误出现在完成 F 之后,但在将其输出分配给 a.
之前鉴于我在函数 F 中得到错误,我误解了一些内部工作,但我不知道是什么。
这是执行输出:
Now comes the error
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0 0x7f1bff9f28b0 in ???
#1 0x7f1bff9f1ae3 in ???
#2 0x7f1bff66c83f in ???
at /build/glibc-vjB4T1/glibc-2.28/signal/../sysdeps/unix/sysv/linux/x86_64/sigaction.c:0
#3 0x562fc494c262 in ???
#4 0x562fc494c3d3 in ???
#5 0x562fc494c30b in ???
#6 0x562fc494c40c in ???
#7 0x7f1bff65909a in __libc_start_main
at ../csu/libc-start.c:308
#8 0x562fc494c0b9 in ???
#9 0xffffffffffffffff in ???
Segmentation fault
对于该函数调用,gfortran 将隐藏参数传递给函数,告诉函数应该将函数结果放在内存中的什么位置。该隐藏参数指定与子例程中的 a
伪参数关联的存储。该存储无效,因为尚未分配与 a
虚拟对象关联的实际参数,因此该函数尝试将其结果放入的存储无效,因此您会在函数内部看到访问冲突。
与赋值语句关联的操作隐含在让函数直接写入赋值左侧事物的存储中。
不同的编译器(或相同的编译器,对于具有不同特征的函数调用或赋值语句)将以不同的方式实现这一点 - 例如,函数可能写入调用代码设置然后复制的临时文件结束,或者可能在调用代码需要释放的函数内部分配缓冲区。
您可以通过检查程序集(将 -S 添加到命令行)或中间表示之一(例如 -fdump-tree-original)来检查 gfortran 编译器如何实现您的程序