Search code examples
pointersfortranderived-typesallocatable-array

Pointer to derived type that contains allocatable array


Generally speaking I want to rename allocatable variables in a derived type that are passed through subroutine arguments. Writing everything with 'derived%type_xx' is not so pleasant. Besides, I don't want to spend extra memory on copying the values of the derived type to a new variable which costs new allocated memory. Furthermore, I know allocatable arrays are preferred than pointers for many reasons. I try to define pointers to the allocatable variable, but failed. I tried this because I want to simplify my code, both to be readable and not to be too long. I wonder if there's a way of achieving the goal? Thanks.

Here's the demonstration code:

Module module_type
IMPLICIT NONE
    TYPE type_1
        REAL,ALLOCATABLE                  ::      longname_1(:), longname_2(:)
    END TYPE
END MODULE

!------------------------------------------------------------------------------------------
SUBROUTINE TEST(input)
    USE MODULE module_type
IMPLICIT NONE
    TYPE(type_1)                          ::      input
    input%longname_1 = input%longname_1 + input%longname_2   ! Use one line to show what I mean
END SUBROUTINE

And here's what failed:

Module module_type
IMPLICIT NONE
    TYPE type_1
        REAL,ALLOCATABLE                  ::      longname_1(:), longname_2(:)
    END TYPE
END MODULE

!------------------------------------------------------------------------------------------
SUBROUTINE TEST(input)
    USE MODULE module_type
IMPLICIT NONE
    TYPE(type_1),TARGET                    ::      input

    REAL,POINTER                           ::      a => input%longname_1 &
                                                 & b => input%longname_2

    a = a + b   ! much better for reading
END SUBROUTINE

It seems like a small issue, but I'd like to read my code without too much pain in the future. So what's the best option? Thanks a lot.


Solution

  • You can use the ASSOCIATE construct to associate a simple name with a more complex designator or expression.

    You could also use the subobjects of the derived type as actual arguments to a procedure that carried out the operation.

    You pointer approach failed because you had a rank mismatch - you were attempting to associate scalar pointers with array targets. You may also have had problems if an explicit interface to your procedure was not available in the calling scope. An explicit interface is required for procedures with dummy arguments with the TARGET attribute.

    Use of pointers for this sort of simple name aliasing may reduce the ability of the compiler to optimize the code. Something like ASSOCIATE should be preferred.