我正在Fortran中编写一个稀疏矩阵库以获得乐趣,但却陷入了困境。我有一个子程序用于矩阵乘法与接口
subroutine matvec(A,x,y)
class(sparse_matrix), intent(in) :: A
real(double_precision), intent(in) :: x(:)
real(double_precision), intent(inout) :: y(:)
{etc.}
这使用了我自己定义的稀疏矩阵类型,其实现并不重要。现在,如果A
包含名为iterator
的对象,我可以使事情变得更好并且代码更少:
type :: sparse_matrix
type(matrix_iterator) :: iterator
{etc.}
存储了一些在matvec
期间跟踪事物的变量。但是,如果我在矩阵乘法期间更改iterator
的状态并依次改变状态A
,编译器将抛出拟合,因为A
具有该子例程的意图(in)。 / p>
假设我改变了一些事情,而是定义
type :: sparse_matrix
type(matrix_iterator), pointer :: iterator
{etc.}
如果在矩阵具有intent(in)的过程中更改迭代器的状态,则没有问题,因为指向迭代器的指针的值不会改变;只有存储在该地址的内存才会受到影响。这是通过减少测试用例来确认的,该测试用例使用GCC进行编译和运行。
我认为这是一个合适的解决方案吗?或者我应该更改子程序,以便A有意图(inout)?它与GCC一起编译的事实并不一定意味着它符合标准,也不意味着它是良好的编程实践。
为了与C类比,假设我有一个函数foo(int* const p)
。如果我写了
*p = 42;
这没关系,因为指针的值不会改变,只有存储在指向的地址的数据。另一方面,我写不出来
p = &my_var;
因为它是一个常量指针。
答案 0 :(得分:2)
是的,没关系。实际上这种做法是众所周知的,例如,在进行引用计数内存管理时使用它,因为定义赋值的右侧是intent(in)
表达式,但您必须能够减少其中的引用计数