Accessing private variable as pointer 
Author Message
 Accessing private variable as pointer

Hi!

I have a question about accessing to private variables from other modules. I
want my code to be to be strict ANSI fortran 95, so compiler independent. My
current compiler is CVF 6.6. The problem (I send an example below) is that I
have a module (Module Test) where I've defined a private variable as a
pointer. I wish to access the values in this pointer variable from other
modules (Module Main) in a way that I cant change it, more or less like an
intent out statement. To do this I call a subroutine (GetmTest) that carries
a pointer as argument that points to my variable. Doing this I am able to
change the values in the variable therefore loosing the private attribute. I
should not be able to do this or not? Maybe I do not yet understand
pointers, but I would like to solve this problem. Is there another way of
doing this operation?

Every help will be greatly appreciated,

Luis Fernandes

http://www.*-*-*.com/

!begin example

Module Test

    private

    public :: ConstructmTest

    public :: GetmTest

    real, private, dimension(:), pointer  :: mTest

    contains

    subroutine ConstructmTest

       allocate(mTest(12))

       mTest = 0.

    end subroutine

    subroutine GetmTest (myTest)

        real, dimension(:), pointer      :: myTest

        myTest => mTest

    end subroutine

end Module Test

Module Main

    use Test

    private

    public :: ConstructMain

    real, private, dimension(:), pointer      :: FirstTest, SecondTest

    contains

    subroutine ConstructMain

        call ConstructmTest

        call GetmTest(FirstTest)

        FirstTest = -99.  !I should not be able to do this

        nullify(FirstTest)

        call GetmTest(SecondTest)

    end subroutine ConstructMain

end Module Main

program MyProblem

     use Test

    use Main

    implicit none

    call ConstructMain

end program MyProblem

 !end example



Sun, 07 Aug 2005 02:11:47 GMT  
 Accessing private variable as pointer


Quote:
>The problem (I send an example below) is that I
> have a module (Module Test) where I've defined a private variable as a
> pointer. I wish to access the values in this pointer variable from other
> modules (Module Main) in a way that I cant change it, more or less like
an
> intent out statement. To do this I call a subroutine (GetmTest) that
carries
> a pointer as argument that points to my variable. Doing this I am able to
> change the values in the variable therefore loosing the private attribute.

I think you need to distinguish the pointer from its target. Your
specification of mTest creates a descriptor that will later point to a
target. You create that target by the allocate of mTest. Next you make
FirstTest point to THE TARGET of mTest. You then fill that target with
values. That's all OK. You haven't in any way touched the status of the
pointer, only the values of its target. A pointer does not have a value,
only an association status (undefined, associated or disassociated).

Does that help?

Regards,

Mike Metcalf



Sun, 07 Aug 2005 04:07:42 GMT  
 Accessing private variable as pointer


Quote:
> I think you need to distinguish the pointer from its target. Your
> specification of mTest creates a descriptor that will later point to a
> target. You create that target by the allocate of mTest. Next you make
> FirstTest point to THE TARGET of mTest. You then fill that target with
> values. That's all OK. You haven't in any way touched the status of the
> pointer, only the values of its target. A pointer does not have a value,
> only an association status (undefined, associated or disassociated).

OK. If I understood, this means that although, I have defined mTest as a
pointer when I allocate it, automatically a target is created. But still
Ive defined mTest as private in Module Test. Why is it, that I am able to
change the values of the target mTest outside Module Test? As mTest is
private I should not be able to do so? Is there a way I can point to target
however preventing it from changing its values?
Thanks for the help. Best regards,

Luis Fernandes
http://www.mohid.com



Sun, 07 Aug 2005 18:34:51 GMT  
 Accessing private variable as pointer
Take a look at C or C++: you can have _two_ "const" (equivalent to
Fortran's INTENT(IN)) qualifiers on what Fortran would call a pointer
dummy argument. One applies to the pointer itself - i.e., you cannot
do pointer assignment or (de)allocation; the other applies to the
target, i.e., you cannot do an assignment or (de)allocation (because
that makes the target potentially inaccessible to the program, which
should be considered equivalent to writing to the target).

As I understand it, Fortran's private or intent qualifiers only apply
to the pointer itself, in these cases, and not to the target.

        Jan



Sun, 07 Aug 2005 22:05:17 GMT  
 Accessing private variable as pointer



Quote:

> As I understand it, Fortran's private or intent qualifiers only apply
> to the pointer itself, in these cases, and not to the target.

One notes that, in F2000, the PROTECTED attribute allows a variable to be
modified only in the module in which it is specified. That still does not
protect the target of a pointer, however. Also in F2000, the INTENT
attributes may be applied to the association status of a pointer, but even
that does not protect the target.

Regards,

Mike



Sun, 07 Aug 2005 23:37:29 GMT  
 Accessing private variable as pointer


Quote:
> One notes that, in F2000, the PROTECTED attribute allows a variable to be
> modified only in the module in which it is specified. That still does not
> protect the target of a pointer, however. Also in F2000, the INTENT
> attributes may be applied to the association status of a pointer, but even
> that does not protect the target.

Is there a feature protecting the target? Should not the F2000 PROTECTED and
INTENT attributes prevent this to happen? Im sorry for so many questions,
but I feel like I am stepping over the private attribute. I can only think
of allocating a new variable each time I want to access the target, fill it
with the target values, and after I used it, deallocate it. But this seems
slow and not very straightforward. Thanks,

Luis



Mon, 08 Aug 2005 19:37:55 GMT  
 Accessing private variable as pointer


Quote:

> Is there a feature protecting the target? Should not the F2000 PROTECTED
and
> INTENT attributes prevent this to happen? Im sorry for so many questions,
> but I feel like I am stepping over the private attribute.

I think the reason for this lack of protection is that the standards do not
require an implementation to keep track of what is pointing to any given
target. That is the reason why the (last) nullify on a pointer doesn't also
deallocate the target. It could be done but it's (apparently) a huge
overhead for compiler writers with implications for efficiency.

Quote:
> I can only think
> of allocating a new variable each time I want to access the target, fill
it
> with the target values, and after I used it, deallocate it. But this seems
> slow and not very straightforward. Thanks,

Well, you've never told us what problem you're actually trying to solve.
It's possible to write perfectly sound code without use of PRIVATE at all.
It's simply one of the safety features built into f90 and as it's there
should be used wherever possible. If it doesn't do quite as much as you
would like, that's no reason, that I can see, to jump through hoops.

Regards,

Mike Metcalf



Mon, 08 Aug 2005 23:41:40 GMT  
 Accessing private variable as pointer
GetmTest could return a pointer to a copy of the target:

subroutine getmTest(returnedValue)
    real, pointer :: returnedValue(:)

    !Check if mTest is pointing at a target
    if(associated(mTest)) then

        !Check if returnedValue already contains stuff we want to ditch
        if(associated(returnedValue)) deallocate(returnedValue)

        !Make space for a copy
        allocate (returnedValue(size(mTest)))

        !Copy mTest
        returnedValue = mTest
    end if
end subroutine

Andy Smith


Quote:
> Hi!

> I have a question about accessing to private variables from other modules.
I
> want my code to be to be strict ANSI Fortran 95, so compiler independent.
My
> current compiler is CVF 6.6. The problem (I send an example below) is that
I
> have a module (Module Test) where I've defined a private variable as a
> pointer. I wish to access the values in this pointer variable from other
> modules (Module Main) in a way that I cant change it, more or less like
an
> intent out statement. To do this I call a subroutine (GetmTest) that
carries
> a pointer as argument that points to my variable. Doing this I am able to
> change the values in the variable therefore loosing the private attribute.
I
> should not be able to do this or not? Maybe I do not yet understand
> pointers, but I would like to solve this problem. Is there another way of
> doing this operation?

> Every help will be greatly appreciated,

> Luis Fernandes

> http://www.mohid.com

> !begin example

> Module Test

>     private

>     public :: ConstructmTest

>     public :: GetmTest

>     real, private, dimension(:), pointer  :: mTest

>     contains

>     subroutine ConstructmTest

>        allocate(mTest(12))

>        mTest = 0.

>     end subroutine

>     subroutine GetmTest (myTest)

>         real, dimension(:), pointer      :: myTest

>         myTest => mTest

>     end subroutine

> end Module Test

> Module Main

>     use Test

>     private

>     public :: ConstructMain

>     real, private, dimension(:), pointer      :: FirstTest, SecondTest

>     contains

>     subroutine ConstructMain

>         call ConstructmTest

>         call GetmTest(FirstTest)

>         FirstTest = -99.  !I should not be able to do this

>         nullify(FirstTest)

>         call GetmTest(SecondTest)

>     end subroutine ConstructMain

> end Module Main

> program MyProblem

>      use Test

>     use Main

>     implicit none

>     call ConstructMain

> end program MyProblem

>  !end example



Tue, 09 Aug 2005 06:51:12 GMT  
 Accessing private variable as pointer

Quote:

>     !Check if mTest is pointing at a target
>     if(associated(mTest)) then

No, the comment is not correct.  This statement does not test that.
(Similar issues with the following associated test also).

If you are going to work with pointers, it is really, really
important to understand what the associated intrinsic does, and
even more important to understand what it does not do.  Have I
mentioned that it is important?

A pointer can have one of *THREE* (not two) states.  It can be
associated, disassociated, or undefined.  You cannot forget
about the possibility of undefined.  If you do so, you won't be
able to write any substantial programs that use pointers and
actually work.  Pointers start "life" undefined, unless you have
done something explicit to make them start otherwise.  And they
can become undefined any of several ways.

It is illegal to even invoke the associated intrinsic on a
pointer whose association status is defined.  If you do so,
the results are unpredictable and are very likely to include
program crashes or bugs.  The associated intrinsic can *ONLY*
distinguish between associated and disassociated; you, the user,
have to have ruled out the possibility of undefined before you
even invoke the associated intrinsic.  There is no way to test
whether or not a pointer is defined; it is not a testable state.
You just have to know.  Yes, that requires special care; it is
one of the reasons that pointers are tricky and bug-prone.

Yes, it is a real problem - not just a theoretical one.
If you ignore this when using pointers, your code *WILL*
crash.  You might be able to write "toy" samples that don't
crash, but any substantial application is pretty much guaranteed
to.

It is possible to program with such care, but when I see a
code comment like the above one, I cringe because anyone who
actually believes the comment will be mislead into writing
buggy code.

--
Richard Maine                       |  Good judgment comes from experience;
email: my last name at host.domain  |  experience comes from bad judgment.
host: altair, domain: dfrc.nasa.gov |        -- Mark Twain



Tue, 09 Aug 2005 07:12:01 GMT  
 Accessing private variable as pointer

Quote:

>snip<
> It is illegal to even invoke the associated intrinsic on a
> pointer whose association status is defined.  If you do so,
> the results are unpredictable and are very likely to include
> program crashes or bugs.
>snip<

You meant use of ASSOCIATED is illegal on an undefined pointer?

I agree that you must take care not to use ASSOCIATED on an undefined
pointer. I had not spotted that the posters code does indeed pass a
potentialy undefined pointer in to GetMTest as I was assuming the poster
would have taken care of the initial state of the pointers. F95 has the
NULL() intrinsic function that allows us to make pointers start life with a
disassociated state. If the posters code used this then my suggested code
would be more reliable.

What benefit does having the undefined state have? Presumably the Fortran
commitee thought it was useful but obviously it causes many problems as you
say.

Andy Smith



Tue, 09 Aug 2005 08:45:38 GMT  
 Accessing private variable as pointer

Quote:



> > It is illegal to even invoke the associated intrinsic on a
> > pointer whose association status is defined.

> You meant use of ASSOCIATED is illegal on an undefined pointer?

Oops.  yes.  I said "defined", but of course meant "undefined".
Sorry if my misstatement contributed to confusion.

Quote:
> What benefit does having the undefined state have? Presumably the Fortran
> commitee thought it was useful but obviously it causes many problems as you
> say.

It isn't a matter of benefit.  It is more a matter of acknowledging the
facts of life.  It would be prohibitively costly for implementations to
avoid such a state.  I'll let others speak to the implementation details,
lest I reveal the true depths of my ignorance.  I don't think that anyone
actively thinks that having an undefined state is a good thing.  It is
just the standard's way of acknowledging that reasonable implementations
are likely to be unable to give you a correct answer.  If the pointer
was previously associated, but its target "disappeared" for some
reason (there are many ways that can happen), the pointer might well
still "appear" to be associated, but if you reference it, you may end
up stepping all over memory now being used for something else (or perhaps
even no longer addressable by this process).

Note that this business of being undefined is not unique to pointers or
new to f90.  Ordinary variables can also get undefined.  As with
pointers, there is no way to test whether or not a variable is undefined.
Being undefined is *NOT*, for example, the same thing as being a NaN.
Any attempt to reference the value of an undefined variable is illegal
and may, in theory, cause program crashes or about anything else.

In practice, referencing an undefined variable will usually cause less
havoc than referencing an undefined pointer.  Do note my qualifications
of "in practice" and "usually".  Exceptions (no pun intended, but...)
exist.  And the two become pretty similar if the undefined variable
gets used for something like an array index.

--
Richard Maine
email: my last name at domain
domain: isomedia dot com



Tue, 09 Aug 2005 10:01:16 GMT  
 Accessing private variable as pointer


Quote:
> Well, you've never told us what problem you're actually trying to solve.

Actually, I'm not trying to solve a problem. I am more trying to prevent
one. The code I work on is hierarchally organized in modules by using the
USE statement. Each module handles some specific kind  of information. The
modules were designed in a way that information to be only modifyed inside
its correspondent module, because the code is handled by a extended number
of persons, each one handling one or more modules. We want to ensure that
information is not violated outside its specific module, in a way that one
programmer can use the information in another module, of which he knows
almost nothing about (just that he wants to access the values of a variable
present in that module), but cannot alter it. Thus, as we found out that
when we access the desired variable by pointing to it and the target values
get unprotected, we aknowledged that risk. The only solution apparently is
to repplicate the target, which consumes execution time, especially when
this type of operation is performed with large matrixes and some millions
times over. As time is important to us, as well as, encapsulation, our
problem is between adding another coding rule to the programmers (accepting
the risks) or increase execution time (taking no risks).

Best regards,

Luis



Tue, 09 Aug 2005 19:12:44 GMT  
 Accessing private variable as pointer


Quote:

> Is there a feature protecting the target? Should not the F2000 PROTECTED
and
> INTENT attributes prevent this to happen? Im sorry for so many questions,
> but I feel like I am stepping over the private attribute. I can only think
> of allocating a new variable each time I want to access the target, fill
it
> with the target values, and after I used it, deallocate it. But this seems
> slow and not very straightforward. Thanks,

I took up these points with Malcolm Cohen, who is not only a recent member
of J3 but also a compiler writer. My questions and his reply follow.

Mike Metcalf

Quote:
>     In f95 it is possible to have a public pointer point at the target of
a
> private pointer and by this means it becomes possible to change the value
of
> that target.
>     In F2000 the PROTECTED attribute prevents overwriting of values from
> outside a given module, but the target of a pointer is not so protected.
> Also, the INTENT of a pointer dummy argument will apply to the association
> status of the pointer and not to its target.
>     Q: what is the reason that a pointer's target can never gain
protection
> from overwriting? Is it just a matter of difficulty of implementation in
> keeping track of what is pointing to a target or am I missing something
> somewhere?

There seems to be several questions here.

Q1: Is (the effect of) PROTECTED modelled on INTENT(IN)?
Ans: Yes.

A2: What is the appropriate thing for INTENT(IN) and a pointer?
Ans: To protect the association status.
     ... because that's what pointers are for, to point to things, not to
     contain a value.

Q3: Why is there no means to protect the target of a pointer (e.g. a
    PROTECTED pointer)?
Ans: There is no consensus on what the semantics of this would be.  A
pointer
     can point at anything, whether that this is protected or not...
     ... at least one member of J3 made a valiant to come up with consistent
     semantics and failed.  IMO it is not possible to have consistent
semantics
     for this.

Actually, the existing situation is two-pronged.  There is a set of compile
time checks (basically the same as for INTENT(IN)) and also some
requirements
that can only be checked at runtime (just like INTENT(IN)).  These checks
are
not terribly difficult though.

Basically, the reason that PROTECTED (in its current form) would not make
much sense even for non-pointer components.  (Think: what happens when
someone
declares a variable of that type outside of the module.  What could that
mean?)  For pointer components it's just totally nonsensical.

If the user wants something dynamic and protected, he'd better make it
ALLOCATABLE rather than POINTER.

Cheers,
--
                        Malcolm Cohen, NAG Ltd., Oxford, U.K.



Sat, 13 Aug 2005 16:13:15 GMT  
 
 [ 13 post ] 

 Relevant Pages 

1. Accessing Private Module Data using pointers?

2. Need global access to pointer variable...

3. private pointer derived data type members

4. Importing via Access 97 odbc driver variable length Access Memo fiels

5. private access to things from arguments of same type

6. Giving a package specification access to the private types of another package

7. Class design: accessing "private" members

8. Class design: accessing "private" members

9. Attempt to access private resource denied

10. Local variables - lifetime and access variables [Q]

11. Accessing a variable of a variable

12. accessing to a variable by ref (variable is an array)

 

 
Powered by phpBB® Forum Software