forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

PRIVATE not implemented properly?

 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support
View previous topic :: View next topic  
Author Message
Keith Waters



Joined: 07 Aug 2007
Posts: 29
Location: London or Somerset, UK

PostPosted: Mon Aug 20, 2007 4:06 pm    Post subject: PRIVATE not implemented properly? Reply with quote

In this program, Module_1 uses a couple of entities (a function and an integer) from Module_2. Module_1 then specifies that the function, M2_Val, will be made PUBLIC. The blank PRIVATE statement ensures that all other entities will be hidden, which in this case means the integer, m2. At least, that is my understanding of the blank PRIVATE statement.

Code:
C DEMO.FOR
      PROGRAM DEMO

      USE Module_1

      m2 = 6

      PRINT *, 'm2     = ', m2
      PRINT *, 'M2_Val = ', M2_Val()

      END

! --------------------------------------------------------------
! MODULE_1.F90
MODULE Module_1

  USE Module_2, ONLY: M2_Val,   &
                      m2

  PRIVATE

  PUBLIC  :: M2_Val

CONTAINS


END MODULE

! --------------------------------------------------------------
! MODULE_2.F90
MODULE Module_2

  PRIVATE

  INTEGER(KIND=SELECTED_INT_KIND(9)) :: m2 = 0

  PUBLIC M2_Val, &
         m2

CONTAINS

  FUNCTION M2_Val ()
    INTEGER(KIND=SELECTED_INT_KIND(9)) :: M2_Val

    M2_Val = m2

  END FUNCTION

END MODULE

The main program USEes Module_1 and attempts to access the integer, m2, directly. The program output is:

m2 = 6
M2_Val = 6

This output demonstrates that the main program has, indeed, been able to access m2 directly. The compiler gives no error message for this. I believe it should.

I’m using the compiler options, /ISO /IMPLICIT_NONE /NO_SCALAR_TO_ARRAY /RESTRICT_SYNTAX /CHECKMATE, and linking with SLINK.

Keith
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7927
Location: Salford, UK

PostPosted: Tue Sep 04, 2007 5:21 pm    Post subject: Reply with quote

This is one of those vague areas where it is difficult to know what the Fortran standard demands. Another popular compiler produces the same results as FTN95 and makes m2 public because is it declared as PUBLIC when it is defined in Module_2.

OK it is used through a sort of inheritance via Module_1 where it is marked as PRIVATE but this is Fortran not C++.

Maybe the compiler should issue a warning when m2 is marked as PRIVATE in Module_1 but this is a minor omission.

At the moment I am assuming that this is not a bug in FTN95.
Back to top
View user's profile Send private message AIM Address
Keith Waters



Joined: 07 Aug 2007
Posts: 29
Location: London or Somerset, UK

PostPosted: Thu Oct 04, 2007 3:35 pm    Post subject: Reply with quote

At the very least this means that the FTN95 help is wrong.

From the FTN90 Help in the section entitled “Modules”, subsection “The PRIVATE and PUBLIC statements”,

Quote: “A PRIVATE statement without a list makes all variables PRIVATE by default.”.

This is wrong and should read, “A PRIVATE statement without a list makes all variables PRIVATE by default unless they have been imported with the USE statement from another module.”.

An alternative wording might be, “A PRIVATE statement without a list makes all variables declared in the module PRIVATE by default. Variables imported from another module with the USE statement remain PUBLIC unless explicitly declared PRIVATE”.

I must say I still find this a complicated interpretation on the part of the FTN95 compiler designers. In my opinion the sensible decision would have been to have the following simple statement apply to all entities in the module, irrespective of whether they have been declared in the module or have been imported from another module.

“A PRIVATE statement without a list makes all data items and procedures PRIVATE by default”

I don’t know if any textbooks on the subject of programming with Fortran 90/95 go along with your interpretation but the one I have, “Fortran 90/95 for Scientists and Engineers” by Stephen J. Chapman, seems to be in the spirit of the interpretation I prefer.

Quote:
"Good Programming Practice
It is good programming practice to hide any module data items or procedures that do not need to be directly accessed by external program units. The best way to hide data items and procedures is to include a PRIVATE statement in each module and then list the specific items that you wish to make visible in a separate PUBLIC statement.”
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7927
Location: Salford, UK

PostPosted: Thu Oct 04, 2007 4:33 pm    Post subject: Reply with quote

Fair enough but the point is a very fine one and one that the standards committe probably didn't even contemplate never mind the poor compiler writers.

Fortran modules are not like C++ classes.

Suppose module A contains a PUBLIC variable x and module B accesses x but makes x PRIVATE from users of B. Module A has to be made available to users of either A or B. So how is the variable x protected from external use? Users can access it directly from module A.

If you want a variable to be private then you should design your modules so that it is defined as private in the base module.
Back to top
View user's profile Send private message AIM Address
Keith Waters



Joined: 07 Aug 2007
Posts: 29
Location: London or Somerset, UK

PostPosted: Thu Oct 04, 2007 10:19 pm    Post subject: Reply with quote

I do take your point about the standards committee probably not even contemplating this.

I’ve never programmed in C++ although I am familiar with object-oriented concepts. And it must be said that the FTN95 help (section “Modules”) does make passing reference.

Quote: “A MODULE can also contain the definition of user-defined types together with the definition of procedures that are common to a number of program units. Some of these procedures may be used to create user-defined operators. In this respect, a MODULE can be designed to be "object oriented".”

In your example modules A and B, I take your point that module A has to be made available to users of A or B, otherwise they cannot compile their program. However, that doesn’t mean they are forced to put a “USE A” statement in their program if they only need to USE module B.

I agree with you that users can access variable x directly from module A. However, with my interpretation of the PRIVATE statement, they have to explicitly state they are going to USE A. I think that’s only right and proper and, to my mind, does provide some protection of x. With the FTN95 interpretation they can access it without doing USE A and I think there is the increased possibility they could inadvertently corrupt it.

Quote:
If you want a variable to be private then you should design your modules so that it is defined as private in the base module.


Yes, but that is not quite what we are talking about. We are talking about entities that need to be exported to a higher-level module but no further.

Perhaps I should put all this into some context. I’ve written some, what I regard as, “low level” modules that implement a Stack, a Dictionary, a Buffer, and a few other esoteric things. Then I have “intermediate level” modules implementing a Document and a Notation. These modules are then used in a “top level” module (let’s call it module Top), which is the only module my users will ever need to reference in a USE statement.

So, I tell my users to place the statement, “USE Top”, in every program unit that needs to use my work. I don’t want them to be able to access the low level Stack, Dictionary, etc. stuff so to get round FTN95’s insistence on ignoring the blank PRIVATE statement for imported entities, I explicitly declare these entities as PRIVATE in my intermediate and top level modules. Of course, they could still access these entities after writing USE Stack, for example, but that would be going against my advice – so my back is covered.

But hang on a minute. These low level Stack, Dictionary, etc modules are generic enough that I might want to make use of them in other projects. When I do, I am again unlikely to want these low level esoteric entities to be propagated up any hierarchy of modules. So whenever I use one of these low level modules I must place the following statement in the using module.

Code:
PRIVATE :: esoteric_entity_1, &
                 esoteric_entity_2, &
                 ….
                 esoteric_entity_n


I think that is a pain but, more importantly, I think it compromises the ease and safety of the module usage.

I suppose this could all be argued and discussed till the cows come home. Perhaps you are right in suggesting that I am thinking in a non-Fortran manner. If that is the case, then I must say I am disappointed in the direction Fortran is taking the Module concept. However, just as you flagged the existence of another compiler that does it the FTN95 way, I can say that I am using a very well known compiler that does it my way.

Regards
Keith
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7927
Location: Salford, UK

PostPosted: Fri Oct 05, 2007 7:49 am    Post subject: Reply with quote

OK, you will naturally use the compiler that best suits your needs.
Back to top
View user's profile Send private message AIM Address
wws



Joined: 25 Oct 2007
Posts: 7
Location: California

PostPosted: Thu Oct 25, 2007 6:54 pm    Post subject: Reply with quote

Unfortunately, FTN95 has implemented this wrongly. The PRIVATE in his Module_1 should prevent m2 from 'leaking through' to the USEr of Module_1. Unless, of course, it is explicitly made public - as is the case of m2_val.

With the /IMPLICIT_NONE option specified, the main program should have given an error message on the use of m2.
Back to top
View user's profile Send private message
tomo.bbe



Joined: 26 Feb 2008
Posts: 3

PostPosted: Fri Mar 14, 2008 3:58 pm    Post subject: Reply with quote

I think the following code is a similar if not the same issue but with derived type components. The following compiles correctly with FTN95 and alters the private attribute in type (m1). Is this a misinterpretation on my part or an ambiguity in the standards?

Code:

module mod1
! Module One
! Simple type (m1) with private contents
! My understanding is that attribute "a" can not be altered by anything
! as there are no methods in this module to do so.
   type m1
      private
      integer :: a = 1
   end type
end module

module mod2
! Module Two
! Type (m2) descends m1
! As the contents of m1 are private routines in mod2 should not be able to alter
! the contents of this attribute on (m2) types.
   use mod1

   type m2
      private
      type (m1) :: m
   end type

contains

   subroutine printm(self)
      ! Simple routine to test that the private condition is violated
      ! for type (m1)
      type (m2) :: self
      ! The calling programme cannot do this so why can this module?
      print *,self%m
      ! Sure self%m%a is a private attribute of self%m and should only
      ! be alterable for module mod1
      self%m%a = 2      
      print *,self
   end subroutine
   
end module


program private
! Programme to test the above modules.
use mod2
! My two types
type (m2) :: two
type (m1) :: one
call printm(two)

! All of the follwoing commands correctly raise errors in the compiler.
!one%a = 2
!two%one%a = 3
!print *,one
!print *,two
!print *,two%two
!print *,two%two%a

end program
Back to top
View user's profile Send private message
Keith Waters



Joined: 07 Aug 2007
Posts: 29
Location: London or Somerset, UK

PostPosted: Sat Mar 15, 2008 10:22 am    Post subject: Reply with quote

I believe this has already been flagged as a bug. I noticed a similar thing discussed here http://forums.silverfrost.com/viewtopic.php?t=853 .

Keith
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7927
Location: Salford, UK

PostPosted: Mon Mar 17, 2008 8:39 am    Post subject: Reply with quote

Thanks.

This bug has already been fixed in the current release (5.20).
Back to top
View user's profile Send private message AIM Address
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group