Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Fortran 2003 question regarding public entries of private types

23 views
Skip to first unread message

Tobias Burnus

unread,
Aug 19, 2007, 4:03:31 PM8/19/07
to
Hello,

I have some interpretation problems with the Fortran 2003 standard:

MODULE mod
IMPLICIT NONE
TYPE, PRIVATE :: hidden
integer :: x
END TYPE hidden
TYPE(hidden), PUBLIC :: one = hidden(5)
END MODULE mod

PROGRAM prog
USE mod, only: one
IMPLICIT NONE
PRINT *, one
PRINT *, one%x
END PROGRAM prog

My question is whether "PRINT *, one" and "PRINT *, one%x" are valid.
(I think the first is not while the second is.)

That "one" can be public although "hidden" is PRIVATE is a change
between Fortran 95 and 2003:

Fortran 95: "If a type definition is private, then the type name, the
structure constructor (4.4.4) for the type, any entity that is of the
type, and any procedure that has a dummy argument or function result
that is of the type are accessible only within the module containing
the definition.

Fortran 2003: "If a type definition is private, then the type name,
and thus the structure constructor (4.5.9) for the type, are
accessible only within the module containing the definition."

I would argue that "PRINT *, one%x" is valid as (Fortran 2003):
"The accessibility of a type does not affect, and is not affected by,
the accessibility of its components".

For "PRINT *, one" I'm believe that it is invalid as type definition
of "hidden" is PRIVATE, but I'm not sure that I have not overlooked
something.

Tobias

Fortran 2003:
---------------
4.5.1.1 Accessibility
Types that are defined in a module or accessible in that module by use
association have either the PUBLIC or PRIVATE attribute. Types for
which an
access-spec is not explicitly specified in that module have the
default
accessibility attribute for that module. The default accessibility
attribute
for a module is PUBLIC unless it has been changed by a PRIVATE
statement
(5.2.1). Only types that have the PUBLIC attribute in that module are
available
to be accessed from that module by use association.
The accessibility of a type does not affect, and is not affected by,
the
accessibility of its components and bindings.
If a type definition is private, then the type name, and thus the
structure
constructor (4.5.9) for the type, are accessible only within the
module
containing the definition.
---------------

Fortran 95:
---------------
4.4.1 Derived-type definition
[...]
The accessibility of a derived type may be declared explicitly by an
access-spec in its derived-type-stmt or in an access-stmt (5.2.3). The
accessibility is the default if it is not declared explicitly. If a
type
definition is private, then the type name, the structure constructor
(4.4.4)
for the type, any entity that is of the type, and any procedure that
has a
dummy argument or function result that is of the type are accessible
only
within the module containing the definition.
If a type definition contains a PRIVATE statement, the component names
for the
type are accessible only within the module containing the definition,
even if
the type itself is public (5.1.2.2). The component names and hence the
internal
structure of the type are inaccessible in any scoping unit accessing
the module
via a USE statement. Similarly, the structure constructor for such a
type shall
be employed only within the defining module.
---------------

Richard Maine

unread,
Aug 19, 2007, 5:15:00 PM8/19/07
to
Tobias Burnus <bur...@net-b.de> wrote:

> MODULE mod
> IMPLICIT NONE
> TYPE, PRIVATE :: hidden
> integer :: x
> END TYPE hidden
> TYPE(hidden), PUBLIC :: one = hidden(5)
> END MODULE mod
>
> PROGRAM prog
> USE mod, only: one
> IMPLICIT NONE
> PRINT *, one
> PRINT *, one%x
> END PROGRAM prog
>
> My question is whether "PRINT *, one" and "PRINT *, one%x" are valid.
> (I think the first is not while the second is.)

They both look fine to me.

> That "one" can be public although "hidden" is PRIVATE is a change
> between Fortran 95 and 2003:

Yes.

> Fortran 95: "If a type definition is private, then ... any entity that is


> of the type, and any procedure that has a dummy argument or function
> result that is of the type are accessible only within the module
> containing the definition.

That was an abberation in f95 caused by people who didn't understand the
language (even though they were writing it :-)). It is a restriction
that serves no particular useful purpose and disallows some coding
practices that would otherwise be perfectly fine and sensible. I've had
to code around it more than once.

> Fortran 2003: "If a type definition is private, then the type name,
> and thus the structure constructor (4.5.9) for the type, are
> accessible only within the module containing the definition."
>
> I would argue that "PRINT *, one%x" is valid as (Fortran 2003):
> "The accessibility of a type does not affect, and is not affected by,
> the accessibility of its components".

I'd agree.



> For "PRINT *, one" I'm believe that it is invalid as type definition
> of "hidden" is PRIVATE, but I'm not sure that I have not overlooked
> something.

No. The fact that the type definition is private is irrelevant.

Public and private are really incredibly simple at the core. All the
confusions (including the above one made by the writers of f95) are
caused by thinking that they are something more complicated than they
are. Well, there is also a bit of confusion caused by the fact that
their names are misleading. :-(

Public means that the name (well, identifier in general, but in this
case, the identifier is a name) is accessible via USE. That is the name
is public. Something like EXPORT might have been a better term, though
PUBLIC isn't too bad.

Private means that the name is not accessible via USE from this module.
PRIVATE is actually a horrid term here and causes much confusion as it
does not mean that the name is necessarily private. It just means that
this module doesn't export it (some other module might in some cases).
But that's not the issue at hand in your case. (It has been in others).

For your case, everything hinges on what the thing is that is exported
by public. The thing in question is the name. That's *ALL*. Just the
name. Private means that the name isn't exported, so you can't get at
that name outside the module. It does *NOT* mean anything else. For
exampe, in the case of a derived type name, it doesn't mean anything
about objects of the type, components, or anything else that doesn't
involve the type name.

--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain

0 new messages