(This was also discussed on comp.lang.fortran: https://groups.google.com/forum/#!topic/comp.lang.fortran/dPaOv53SGeA)
ifort does not compile s1 in the attached code (while accepting s2 and s3 which do essentially the same thing):
$ ifort -c test.f90 -o test.o test.f90(17): error #6780: A dummy argument with the INTENT(IN) attribute shall not be defined nor become undefined. [VAR] var%i = 3 ---^ compilation aborted for test.f90 (code 1) $ ifort -V Intel(R) Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 184.108.40.206 Build 20160204
This seems a bug in ifort, since the assignment defines the target of the pointer, not the pointer itself.
Here is the code
module m implicit none type, abstract :: t_a end type t_a type, extends(t_a), abstract :: t_b integer, pointer :: i => null() end type t_b contains subroutine s1(var) class(t_a), intent(in) :: var select type(var); class is(t_b) var%i = 3 end select end subroutine s1 subroutine s2(var) class(t_b), intent(in) :: var var%i = 3 end subroutine s2 subroutine s3(var) class(t_a), intent(in) :: var integer, pointer :: tmp select type(var); class is(t_b) tmp => var%i tmp = 3 end select end subroutine s3 end module m
Steve Lionel (Intel) wrote:
Escalated as issue DPD200411900, Odd that we didn't see this before. The error doesn't occur if the dummy isn't polymorphic. Thanks.
OK, thank you!
Am I missing something here?
In s1 and s2, why is var%i=3 permitted when var is declared as intent(in)?
In s3, similar issue where var is declared as intent(in) and the pointer tmp is defined to point to var. Doesn't the pointer "inherit" the intent(in) of that which it points to?
The question of what INTENT means for pointers has come up in standard discussions over the years. The result was that the standard says INTENT applies only to the definition status of the pointer itself - NOT the target it points to. In the program here, it is the target being modified and that is not protected by INTENT(IN).
I see - an ambiguity between the actual object and the abstraction of the object.
In Fortran, the expressions containing either, it is indistinguishable.
type, abstract :: t_a end type t_a type, extends(t_a), abstract :: t_b #if defined(USE_POINTER) integer, pointer :: i => null() #else integer :: i #endif end type t_b contains subroutine s1(var) class(t_a), intent(in) :: var select type(var); class is(t_b) var%i = 3 ! syntax indistinguishable between I being pointer or scalar integer end select end subroutine s1
Well, the syntax is the same but the compiler can tell based on the attributes of the component i. This isn't unusual in the language. A reference to X could be a scalar, an array a named constant or even a function. It's all in the declaration.
PURE subroutine s2(var) class(t_b), intent(in) :: var var%i = 3 ! (i is pointer) end subroutine s2
Wouldn't the above be both pure and un-pure?