Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28499 Discussions

Accessing private components of a public type is allowed in Intel Fortran, why?

haifeng2009
Beginner
1,055 Views

Hello,

Here isa possible wrong Fortran programming found in a big Fortran code that Intel Fortran didn't generate error message when compiling. The situation is reproduced in the following simple code.

The problem is accessing A%ivalue%i=-100 outside of the module because this component has private attribute. The intel fortran reference manual says:

"If the derived type is declared PUBLIC in a module, but its components are declared PRIVATE, any scoping unit accessing the module though use association (or host association) can access the derived-type definition, but not its components."

My understanding is that declaring A using myType2 in program main is allowed, but accessing the private component ivalue%i is not. Did I miss something?

Thanks,
Haifeng

[cpp]module myType_mod

    type,private  :: myType1
        integer        :: i
    endtype myType1
    
    type,public   :: myType2
        type(myType1)     :: ivalue
    endtype myType2
        
end module myType_mod

program main
        
    use myType_mod
    
    type(myType2)     :: A
    
    A%ivalue%i = -100
    
end program main  







[/cpp]
0 Kudos
5 Replies
MDK
Beginner
1,055 Views
Quoting - haifeng2009
[cpp]module myType_mod

type,private :: myType1
integer :: i
endtype myType1

 type, public :: myType2
private
type(myType1) :: ivalue
end type myType2
[/cpp]



end module myType_mod

program main

use myType_mod

type(myType2) :: A

A%ivalue%i = -100

end program main


In your sample code, the components of myType2 are not private. As far as I know, the default access in Fortran is public for all entities; that is, you need to explicitly declare something PRIVATE if you want it to be private.

Try this:

[plain] type, public :: myType2
private
type(myType1) :: ivalue
end type myType2[/plain]

Now, myType2 is a public type (and the PUBLIC attribute is redundant) but its components are private (and the PRIVATE specifier is necessary).
0 Kudos
Steven_L_Intel1
Employee
1,055 Views
MDK, you are very close, but not quite on target. The question is about component i of myType1, not myType2.

In haifeng2009's code, the type myType1 is private, which means that the program cannot declare an object of that type. However, it doesn't do that - it references a component of the type through myType2, which is public. What is apparently wanted here is for the components of myType1 to be private, which as MDK says, is done by adding a PRIVATE statement before the components desired to be private. If you do that, Intel Fortran complains:

error #6292: The parent type of this field is use associated with the PRIVATE fields attribute

which is correct.
0 Kudos
haifeng2009
Beginner
1,055 Views
Thanks all for the reply.

I was trying to understand whether my original code valid in Fortran standard. If not (which I think is), then I am wondering whether Intel Fortranmissed this situation when compiling.

I should modify the code a little bit for clearness. I added a new component "fvalue" to myType2. Now the intention is to make myType2 public except component "ivalue". Accessing "A%fvalue = 3.14" in the program is all right, but not "A%ivalue%i = -100" (?)

Haifeng
[cpp]

module myType_mod type,private :: myType1 integer :: i endtype myType1 type,public :: myType2 type(myType1) :: ivalue real :: fvalue endtype myType2 end module myType_mod program main use myType_mod type(myType2) :: A A%ivalue%i = -100 A%fvalue = 3.14 end program main [/cpp]


0 Kudos
MDK
Beginner
1,055 Views
Quoting - haifeng2009
Thanks all for the reply.

I was trying to understand whether my original code valid in Fortran standard. If not (which I think is), then I am wondering whether Intel Fortranmissed this situation when compiling.

I should modify the code a little bit for clearness. I added a new component "fvalue" to myType2. Now the intention is to make myType2 public except component "ivalue". Accessing "A%fvalue = 3.14" in the program is all right, but not "A%ivalue%i = -100" (?)

Haifeng
[cpp]

module myType_mod

type,private :: myType1
integer :: i
endtype myType1

type,public :: myType2
type(myType1) :: ivalue
real :: fvalue
endtype myType2

end module myType_mod

program main

use myType_mod

type(myType2) :: A

A%ivalue%i = -100
A%fvalue = 3.14

end program main [/cpp]



This will make the components of myType1 private:
[plain] type,private :: myType1
    private 
    integer :: i
 end type myType1
[/plain]

myType2 will still be able to access ivalue%i because it's in the same module, but ivalue%i will not be accessible in your your main program. However, ivalue itself--specifically, any public procedures that operate on a myType1 variable--will still be accessible because myType2 has public components.

0 Kudos
Steven_L_Intel1
Employee
1,055 Views
Your original code is valid Fortran and no error is warranted.
0 Kudos
Reply