1

I'm writing a sparse matrix library in Fortran for fun but came into a little snag. I have a subroutine for matrix multiplication with the interface

subroutine matvec(A,x,y)
    class(sparse_matrix), intent(in) :: A
    real(double_precision), intent(in) :: x(:)
    real(double_precision), intent(inout) :: y(:)
    {etc.}

This uses a sparse matrix type that I've defined myself, the implementation of which is unimportant. Now, I can make things nicer and have a lot less code if A contains an object called iterator:

type :: sparse_matrix
    type(matrix_iterator) :: iterator
    {etc.}

which stores a few variables that keep track of things during matvec. But, if I change the state of iterator and in turn the state of A during matrix multiplication, the compiler will throw a fit because A has intent(in) for that subroutine.

Suppose I change things around and instead define

type :: sparse_matrix
    type(matrix_iterator), pointer :: iterator
    {etc.}

It's no problem if I change the state of iterator during a procedure in which a matrix has intent(in), because the value of the pointer to iterator doesn't change; only the memory stored at that address is affected. This is confirmed by making a reduced test case, which compiles and runs just fine using GCC.

Am I correct in thinking this is an appropriate fix? Or should I change the subroutine so that A has intent(inout)? The fact that it compiled with GCC doesn't necessarily mean it's standard-compliant, nor does it mean it's good programming practice.

To make an analogy with C, suppose I had a function foo(int* const p). If I wrote

*p = 42;

this would be ok, as the value of the pointer doesn't change, only the data stored at the address pointed to. On the other hand, I couldn't write

p = &my_var;

because it's a constant pointer.

4

1 回答 1

2

是的,没关系。实际上这种做法是众所周知的,例如在进行引用计数内存管理时使用它,因为定义赋值的右侧是一个intent(in)表达式,但您必须能够减少其中的引用计数。

于 2013-11-22T20:20:18.190 回答