Using compiler versions:
Intel(R) Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 18.0.1.163 Build 20171018 GNU Fortran (GCC) 7.3.1 20180303 (Red Hat 7.3.1-5)
In the short program below, which contains only declarations:
program pointer_to_component implicit none type data logical :: used= .false. real :: val end type data type(data), dimension(3), target :: vdat type(data), pointer :: dat1p => vdat(1), dat2p => vdat(2), dat3p => vdat(3) logical, pointer :: ldat1 => dat1p%used, ldat2 => dat2p%used, ldat3 => dat3p%used ! DEC 1 logical, pointer :: ldat1 => vdat(1)%used, ldat2 => vdat(2)%used, ldat3 => vdat(3)%used ! DEC 2 end program pointer_to_component
Comment out either the line "DEC 1" or "DEC 2" for compilation.
With "DEC 1", ifort issues the error messages:
pointer_to_component.f90(9): error #8813: The target must have the TARGET attribute. [DAT1P] logical, pointer :: ldat1 => dat1p%used, ldat2 => dat2p%used, ldat3 => dat3p%used -----------------------------^
with similar messages for ldat2 and ldat3. However, gfortran compiles the code without complaining.
With "DEC 2", both compilers accept the code.
More interestingly, if I move the declarations into a module and make the conflicting pointer assignments in the program, as below:
module M_PtC type data logical :: used= .false. real :: val end type data type(data), dimension(3), target :: vdat type(data), pointer :: dat1p => vdat(1), dat2p => vdat(2), dat3p => vdat(3) logical, pointer :: ldat1 => null(), ldat2 => null(), ldat3 => null() end module M_PtC program pointer_to_component use M_PtC implicit none ldat1 => dat1p%used ; ldat2 => dat2p%used ; ldat3 => dat3p%used ! DEC 1 end program pointer_to_component
Then both compiler accept the code.
I wonder, when ifort issues an error with the "DEC 1" line, is it following the standard (and thus gfortran is not), or is it a bug? Is it against the standard to assign a pointer to an object component, when the object itself is already a pointer?
I would say that this is an ifort bug.
F2008 says, "If an object has the TARGET attribute, then all of its nonpointer subobjects also have the TARGET attribute."
and:
NOTE 5.24
Every object designator that starts from an object with the TARGET attribute will have either the TARGET or POINTER attribute. If pointers are involved, the designator might not necessarily be a subobject of the original object, but because pointers may point only to entities with the TARGET attribute, there is no way to end up at a nonpointer that does not have the TARGET attribute.
dat1p is itself a pointer, and can only point to something that is a target. Note that the reference to dat1p in the pointer assignment of ldat1 is to the target of dat1p, which must have TARGET or it couldn't have been pointer-assigned at all.
Dear Steve, thanks for the info.
Should I send some comment to someone working in the development of the compiler?
Steve Lionel (Ret.) wrote:
I would say that this is an ifort bug.
F2008 says, "If an object has the TARGET attribute, then all of its nonpointer subobjects also have the TARGET attribute."
and:
NOTE 5.24
Every object designator that starts from an object with the TARGET attribute will have either the TARGET or POINTER attribute. If pointers are involved, the designator might not necessarily be a subobject of the original object, but because pointers may point only to entities with the TARGET attribute, there is no way to end up at a nonpointer that does not have the TARGET attribute.dat1p is itself a pointer, and can only point to something that is a target. Note that the reference to dat1p in the pointer assignment of ldat1 is to the target of dat1p, which must have TARGET or it couldn't have been pointer-assigned at all.
Yes - https://supporttickets.intel.com/?lang=en-US
For more complete information about compiler optimizations, see our Optimization Notice.