Pointer to protected variable

Consider the following snippet:

module string_mod
implicit none
character(len=8), protected, target :: str = 'abcdefgh'
contains
    function ptr_to_str()
        character(len=:), pointer :: ptr_to_str
        ptr_to_str => str
    end function
end module

program test
    use string_mod
    implicit none
    character(len=:), pointer :: p
    p => ptr_to_str()
    print *, p
    p = repeat('a',len(p))
    print *, p
end program

Is it allowed to modify the protected variable via the pointer returned by the procedure? The constraints in 8.5.15 (J3/24-007) only talk about use association.

Paragraph 2 of 8.5.15 says:

Other than within the module in which an entity is given the PROTECTED attribute, or within any of its descendants,

  • if it is a nonpointer object, it is not definable, and

Since str is not a pointer object, I suspect what I’m doing here is “illegal”.

Related questions:

Output of a few compilers:

> nagfor test_protected.f90 
NAG Fortran Compiler Release 7.2(Shin-Urayasu) Build 7203
[NAG Fortran Compiler normal termination]
> ./a.out
 abcdefgh
 aaaaaaaa
> gfortran test_protected.f90 
> ./a.out
 abcdefgh
 aaaaaaaa

The code is valid. As you found, the protected attribute prohibits changing the definition status of the pointer (from outside the module in this case). There is not currently a feature that blocks redefinition of the target. There was a proposal to do this for F2023 but it did not get completed; it’s not officially on the work list for F202Y.

So that means protected only applies through use association? Seems kind of strange it is so easy to “defeat” the protection.

I think the idea is that the programmer has control over access to the variable from rather strict to moderate to almost open. Making it a public target is the “almost open” end of the spectrum. Making a setter function (with public or private attribute) is in the moderate range, and making it only private to the module with no outside access at all is in the strict range. However, even in this latter case, there are some workarounds that can allow the variable to be modified outside of the module (e.g. through a subroutine argument list or through local pointer=>target associations). I’m unsure how much the compiler is expected to do to support the programmer’s intentions in some of these cases.

1 Like