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

SAVE attribute in module

699 views
Skip to first unread message

news.solani.org

unread,
Jun 6, 2012, 3:59:29 AM6/6/12
to
Dear Fortran Guru's,

I have a problem with a piece of code which may be summarized as follows:

MODULE somemodule

IMPLICIT NONE

TYPE sometype
INTEGER :: i
DOUBLE PRECISION, POINTER, DIMENSION(:,:) :: coef => NULL()
END TYPE sometype

TYPE(sometype) :: somevariable

CONTAINS

...
...
END MODULE somemodule


The problem I have is that on some compilers this compiles and runs
perfectly fine whereas other compilers complain and say that the
declaration:

TYPE(sometype) :: somevariable

should be:

TYPE(sometype), SAVE :: somevariable

To my (sometime limited) understanding of the fortran 95 standard module
variables are "SAVE" by default! So I do not understand why a compiler would
"demand" this. It seems that it is related to the NULLIFY statement in the
type declaration. So I was wondering whether that might be something
non-standard!?

So my main question is, how should the piece of code look in proper fortran
95 (f90, f2003, and/or f2008) standard. Is the compiler right to "demand"
the save statement? Is the NULLIFY in the type allowed according to the
standard or not?

Many thanks for any help you can give me on this topic!

Cheers,
Tim

---------------------
Destiny is not a matter of chance
....it is a matter of choice
It is not something to be waited for
....it is something to be achieved


Wolfgang Kilian

unread,
Jun 6, 2012, 5:44:23 AM6/6/12
to
IIRC, in the newest standard F2008 (or was it 2003?), the SAVE attribute
is implied for all module variables, so SAVE is redundant (but allowed).
In older standards, there was the possibility of non-saved module
variables. If the corresponding module goes 'out of scope', i.e., there
is no entity in use at a given time that refers to this module, the
value of the variable becomes undefined.

That said, apparently nobody had a use for non-saved module variables,
so in the latest revision this possibility was eliminated. The advice
is to write an explicit SAVE for all module variables unless you compile
the program only with compilers that explicitly support that standard.

>
> So my main question is, how should the piece of code look in proper
> fortran 95 (f90, f2003, and/or f2008) standard. Is the compiler right to
> "demand" the save statement? Is the NULLIFY in the type allowed
> according to the standard or not?
>
> Many thanks for any help you can give me on this topic!
>
> Cheers,
> Tim
>
> ---------------------
> Destiny is not a matter of chance
> ....it is a matter of choice
> It is not something to be waited for
> ....it is something to be achieved
>
>

-- Wolfgang

--
E-mail: firstnameini...@domain.de
Domain: yahoo

Richard Maine

unread,
Jun 6, 2012, 10:56:00 AM6/6/12
to
news.solani.org <springi...@excite.com> wrote:

> To my (sometime limited) understanding of the fortran 95 standard module
> variables are "SAVE" by default! So I do not understand why a compiler would
> "demand" this. It seems that it is related to the NULLIFY statement in the
> type declaration. So I was wondering whether that might be something
> non-standard!?

Your understanding is incorrect, at least for anything other than f2008.
I believe that f2008 made module variables SAVE by default. However, no
previous standard did. (And you are unlikely to have even an f2003
compiler, much less an f2008 one). To my knowledge, all compilers
implemented modules in such a way that they might as well have been
SAVEd. However, that was definitely not a specification of the standard
- just an implementation choice that turned out to be universal. F2008
added such a specification in the standard.

I'm not yet awake enough to be certain or to feel like dragging out the
standard to check, but yes, I believe that the default initialization is
related to the problem you observed. (As a nitpick about terminology,
there is no NULLIFY statement in the code shown, but I'm sure that you
mean the nullification in the default initialization). I think that the
standard might require that a variable with default initialization have
the SAVE attribute. If so, that would be a requirement on your code, not
on a compiler. Thus a compiler would be correct to complain about your
omission of the SAVE attribute.

> So my main question is, how should the piece of code look in proper
> fortran 95 (f90, f2003, and/or f2008) standard. Is the compiler right to
> "demand" the save statement? Is the NULLIFY in the type allowed according
> to the standard or not?

Unless you are restricting your code to f2008 compilers (none of which
exist), you should specify the SAVE attribute and the compiler is
correct to complain about your failure to do so.

As noted above, there is no "NULLIFY" in the code, but the default
initialization is fine as of f95, provided you use the SAVE attribute.
Default initialization was not a feature of the f90 standard at all; it
was one of the fairly few things introduced in f95.

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

Tobias Burnus

unread,
Jun 6, 2012, 11:07:27 AM6/6/12
to
On 06/06/2012 11:44 AM, Wolfgang Kilian wrote:
> On 06/06/2012 09:59 AM, news.solani.org wrote:
>> TYPE sometype
>> INTEGER :: i
>> DOUBLE PRECISION, POINTER, DIMENSION(:,:) :: coef => NULL()
>> END TYPE sometype
>>
>> TYPE(sometype) :: somevariable
>
>> The problem I have is that on some compilers this compiles and runs
>> perfectly fine whereas other compilers complain and say that the
>> declaration:
>>
>> TYPE(sometype) :: somevariable
>>
>> should be:
>>
>> TYPE(sometype), SAVE :: somevariable
>>
>> To my (sometime limited) understanding of the fortran 95 standard module
>> variables are "SAVE" by default! So I do not understand why a compiler
>> would "demand" this. It seems that it is related to the NULLIFY
>> statement in the type declaration. So I was wondering whether that might
>> be something non-standard!?

> IIRC, in the newest standard F2008 (or was it 2003?), the SAVE attribute
> is implied for all module variables, so SAVE is redundant (but allowed).

It's Fortran 2008; from page xv of the standard: "Module enhancements:
[...] Data objects and procedure pointers declared in a module
implicitly have the SAVE attribute."


> In older standards, there was the possibility of non-saved module
> variables. If the corresponding module goes 'out of scope', i.e., there
> is no entity in use at a given time that refers to this module, the
> value of the variable becomes undefined.

Independent of the standard, it looks like a compiler bug. The default
initialization should work independently whether the module variable has
the save attribute or not.


>> So my main question is, how should the piece of code look in proper
>> fortran 95 (f90, f2003, and/or f2008) standard. Is the compiler right to
>> "demand" the save statement? Is the NULLIFY in the type allowed
>> according to the standard or not?

I think the default initialization (or at least the default NULL()
initialization?) is a Fortran 95 feature, thus, a Fortran 90 solution is
to remove it.

Otherwise, it looks like valid Fortran 95 to 2008.

As a pragmatic solution: Simply add a SAVE statement in your module;
that marks all variables/proc-pointers with that attribute and you do
not have to worry about that compiler nor about whether you correctly
access the module variable in case the implementation (theoretically)
has chosen to have non-SAVE module variables.

If you wrongly access the modules, the program becomes invalid Fortran
90/95/2003. Though as Wolfgang wrote, (nearly?) all compilers put all
module variables in static memory. Example:

module m
integer :: i
end module m

subroutine one()
use m
i = 5
end subroutine one

subroutine two()
use m
print *, i ! Invalid if "i" is not SAVE
end subroutine two

call one()
! << module "m" is nowhere use-associated at that point
call two()
end

Richard Maine

unread,
Jun 6, 2012, 11:27:01 AM6/6/12
to
Tobias Burnus <bur...@net-b.de> wrote:

> Independent of the standard, it looks like a compiler bug. The default
> initialization should work independently whether the module variable has
> the save attribute or not.

Since there seems to be disagreement about this, I suppose I better wake
up enough to check the standard. Anyway, I have at least some tea in my
by now....

Yep, I found the specification that I thought I recalled. I disagree
with what I think Tobias is saying above. I do see a compiler bug, but
the bug I see is in those compilers that fail to complain.

In f2003 (becaus ethat was what was most readily at hand), see C1107

"If an object of a type for which component initialization is
specified (R444) appears in the specification-part of a module and
does not have the allocatable or pointer attribute, the object shall
have the SAVE attribute."

This being a constraint, a compiler is required to have the capability
of diagnosing a violation of it.

I vaguely recall some discussion about the reasons for this constraint,
but it would take a bit of work for me to turn that vague recollection
into something coherent.

James Van Buskirk

unread,
Jun 6, 2012, 11:46:44 AM6/6/12
to
"Tobias Burnus" <bur...@net-b.de> wrote in message
news:4FCF722F...@net-b.de...

> On 06/06/2012 11:44 AM, Wolfgang Kilian wrote:

>> In older standards, there was the possibility of non-saved module
>> variables. If the corresponding module goes 'out of scope', i.e., there
>> is no entity in use at a given time that refers to this module, the
>> value of the variable becomes undefined.

> Independent of the standard, it looks like a compiler bug. The default
> initialization should work independently whether the module variable has
> the save attribute or not.

Yeah, but default initialization for unsaved module variables would
have been ugly, which is why no standard ever permitted it. For
unsaved variables without default initialization (nor allocatability)
implementation as a saved variable seems OK because when the module
goes out of scope and then comes back into scope any old value of
the variable is fine. With default initialization the Fortran
processor would have to arrange for default initialization to
happen every time the variable comes back into scope so some sort
of data structure would have to be around to make sure that the
processor knew when this was happening for each unsaved module
variable with default initialization. Or does a variable come into
scope even though it is excluded as a consequence of USE with ONLY?
If you point a pointer at an unsaved module variable and then the
module goes out of scope does the pointer have undefined association
status?

The necessity of maintaining these data structures and the probable
result that users would just freak out when you got them working
correctly so that the processor silently reset the module variables
to their default-initial state when they came back into scope was
such an awkward potential feature that the whole concept was
forbidden from the very beginning.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


Tobias Burnus

unread,
Jun 6, 2012, 3:56:34 PM6/6/12
to
Richard Maine wrote:
> Tobias Burnus<bur...@net-b.de> wrote:
>> Independent of the standard, it looks like a compiler bug. The default
>> initialization should work independently whether the module variable has
>> the save attribute or not.
>
> Yep, I found the specification that I thought I recalled. I disagree
> with what I think Tobias is saying above. I do see a compiler bug, but
> the bug I see is in those compilers that fail to complain.

Thanks for checking. I think I have read too much in the Fortran 2008
standard during the last two years.

* * *

I just saw that in case of gfortran, the constraint check fails. That
is: In GCC 4.6/4.7/4.8, the constraint is no longer diagnosed with
-std=f95/-std=f2003; while gfortran 4.5 properly complains:

TYPE(sometype) :: somevariable
1
Error: Fortran 2008: Implied SAVE for module variable 'somevariable' at
(1), needed due to the default initialization


(As GCC 4.1 to 4.3 didn't support -std=f2008, they always complain. As
does GCC 4.4, which has -std=f2008 but not yet that feature.)

The check is actually still present in the newer version, only module
variables are now also internally marked as implied save, which broke
the test. That shows that one cannot have too many test cases. The bug
will be soon be fixed.


> In f2003 (becaus ethat was what was most readily at hand), see C1107
>
> "If an object of a type for which component initialization is
> specified (R444) appears in the specification-part of a module and
> does not have the allocatable or pointer attribute, the object shall
> have the SAVE attribute."
>
> This being a constraint, a compiler is required to have the capability
> of diagnosing a violation of it.

Unless it supports that part of Fortran 2008 ... (One can still argue
that it should support checking for F95, F2003 besides F2008, especially
if the support of F2008 [and F2008] is incomplete.)


Tobias

glen herrmannsfeldt

unread,
Jun 6, 2012, 6:24:46 PM6/6/12
to
James Van Buskirk <not_...@comcast.net> wrote:

(snip, someone wrote)
>> Independent of the standard, it looks like a compiler bug. The default
>> initialization should work independently whether the module variable has
>> the save attribute or not.

> Yeah, but default initialization for unsaved module variables would
> have been ugly, which is why no standard ever permitted it. For
> unsaved variables without default initialization (nor allocatability)
> implementation as a saved variable seems OK because when the module
> goes out of scope and then comes back into scope any old value of
> the variable is fine.

For COMMON, the only case that I knew of was when one was in an
overlay. As far as I know, that can still be true for module
variables, assuming one is using overlays.

But overlay is usually done by the linker, and it might be that
not all systems give the compiler enough control over things
to stop someone from putting a COMMON block or module into
an overlay. Some put them into the root segment by default,
but maybe not all.

> With default initialization the Fortran
> processor would have to arrange for default initialization to
> happen every time the variable comes back into scope so some sort
> of data structure would have to be around to make sure that the
> processor knew when this was happening for each unsaved module
> variable with default initialization.

With the usual static overlay structure that might naturally happen.
Then again, it might still surprise someone.

(snip)

> The necessity of maintaining these data structures and the probable
> result that users would just freak out when you got them working
> correctly so that the processor silently reset the module variables
> to their default-initial state when they came back into scope was
> such an awkward potential feature that the whole concept was
> forbidden from the very beginning.

-- glen

Richard Maine

unread,
Jun 6, 2012, 6:46:35 PM6/6/12
to
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

> James Van Buskirk <not_...@comcast.net> wrote:
>
> (snip, someone wrote)
> >> Independent of the standard, it looks like a compiler bug. The default
> >> initialization should work independently whether the module variable has
> >> the save attribute or not.
>
> > Yeah, but default initialization for unsaved module variables would
> > have been ugly, which is why no standard ever permitted it. For
> > unsaved variables without default initialization (nor allocatability)
> > implementation as a saved variable seems OK because when the module
> > goes out of scope and then comes back into scope any old value of
> > the variable is fine.
>
> For COMMON, the only case that I knew of was when one was in an
> overlay. As far as I know, that can still be true for module
> variables, assuming one is using overlays.
>
> But overlay is usually done by the linker, and it might be that
> not all systems give the compiler enough control over things
> to stop someone from putting a COMMON block or module into
> an overlay. Some put them into the root segment by default,
> but maybe not all.

I'm not sure I quite follow the relevance here, but that's not unusual
for me when reading Glen's posts. Yes, there have been implementations
of COMMON where the SAVE attribute mattered. In addition to overlay,
there was the CDC segloader, which admitedly was a lot like an overlay,
though it didn't use that term. Guess I don't know why it matters,
though, other than that, yes, implementations existed.

Note that variables with default initialization are prohibitted from
being in COMMON at all, so the question of the SAVE attribute doesn't
come up there. I suspect that prohibition was for simillar reasons as
the requirement for them to be SAVE'd in modules, but that the solution
was different because nobody much cared about allowing these newfangled
things in COMMON, so they were just prohibitted.

> > With default initialization the Fortran
> > processor would have to arrange for default initialization to
> > happen every time the variable comes back into scope so some sort
> > of data structure would have to be around to make sure that the
> > processor knew when this was happening for each unsaved module
> > variable with default initialization.
>
> With the usual static overlay structure that might naturally happen.
> Then again, it might still surprise someone.

So if one imagines one particular implementation strategy - one which
has never been used fo rmodules, but might plausibly be done by
comparison to some old implementations of COMMON - then it might be easy
to do. Yup. And sometimes the Fortran standard does indeed do things
that strongly encourage particular implementation strategies like that.
But there are usually pretty strong reasons for such requirements. There
sure weren't very strong arguments made for allowing nonsaved module
variables with default initialization. To the contrary, note that it was
decided for f2008 that there was insufficient reason to even have such a
thing as a nonsaved module variable at all. (I'm not entirely sure I
like that decision, as it seems to close off implementation choices that
might make sense on some architectures, but perhaps that never would
have been relevant anyway).

glen herrmannsfeldt

unread,
Jun 6, 2012, 7:01:47 PM6/6/12
to
Richard Maine <nos...@see.signature> wrote:

(snip, I wrote)
>> For COMMON, the only case that I knew of was when one was in an
>> overlay. As far as I know, that can still be true for module
>> variables, assuming one is using overlays.

>> But overlay is usually done by the linker, and it might be that
>> not all systems give the compiler enough control over things
>> to stop someone from putting a COMMON block or module into
>> an overlay. Some put them into the root segment by default,
>> but maybe not all.

> I'm not sure I quite follow the relevance here, but that's not unusual
> for me when reading Glen's posts. Yes, there have been implementations
> of COMMON where the SAVE attribute mattered. In addition to overlay,
> there was the CDC segloader, which admitedly was a lot like an overlay,
> though it didn't use that term. Guess I don't know why it matters,
> though, other than that, yes, implementations existed.

The other reason for the comment was that in either the overlay
or CDC segloader case, it might be that the compiler doesn't have
the ability to keep a segment from being overlayed.

Now, there might not be any Fortran 95 compilers for the CDC machines,
or for ones that still have overlay linkers, so it might not matter.

> Note that variables with default initialization are prohibitted from
> being in COMMON at all, so the question of the SAVE attribute doesn't
> come up there. I suspect that prohibition was for simillar reasons as
> the requirement for them to be SAVE'd in modules, but that the solution
> was different because nobody much cared about allowing these newfangled
> things in COMMON, so they were just prohibitted.

That makes some sense.

-- glen

Tim Springer

unread,
Jun 7, 2012, 9:03:06 AM6/7/12
to
> Unless you are restricting your code to f2008 compilers (none of which
> exist), you should specify the SAVE attribute and the compiler is
> correct to complain about your failure to do so.

Thanks Richard (and others) for the clear answer(s).
Hmm, that's bad, I thought the SAVE was default.... Will have to check my
code carefully then. However, it seems most compilers make module variables
SAVE by default....

> As noted above, there is no "NULLIFY" in the code, but the default
> initialization is fine as of f95, provided you use the SAVE attribute.
> Default initialization was not a feature of the f90 standard at all; it
> was one of the fairly few things introduced in f95.

Hmm, I seem to have another gap in my knowledge here. Your remarks seems to
indicate that there is a difference between a statement like:
somepointer => NULL()

and
NULLIFY(somepointer)

I know that "NULLIFY" can not be used for default initialization. But are
there more differences?


MECEJ4

unread,
Jun 7, 2012, 10:49:38 AM6/7/12
to
On 6/7/2012 8:03 AM, Tim Springer wrote:
<...CUT...>

> Hmm, I seem to have another gap in my knowledge here. Your remarks seems to
> indicate that there is a difference between a statement like:
> somepointer => NULL()
>
> and
> NULLIFY(somepointer)
>
> I know that "NULLIFY" can not be used for default initialization. But are
> there more differences?
>
>
There are definite rules as to when default initialization is made. On
the other hand, NULLIFY() is completely under your control.

Let us say you have a pointer variable which you have properly
associated and used. Now, you want to do something else before you come
back to further reactivating that pointer, and want to make sure that
there is no unforeseen usage of that pointer. You can use NULLIFY on
that pointer, and as long as you don't use the pointer without checking
for validity/association, you are save from that unforeseen usage. Later
in the same program, you can associate the pointer with something else.

-- mecej4

Richard Maine

unread,
Jun 7, 2012, 12:03:18 PM6/7/12
to
Tim Springer <Tim.Sp...@PosiTim.com.invalid> wrote:

> > Unless you are restricting your code to f2008 compilers (none of which
> > exist), you should specify the SAVE attribute and the compiler is
> > correct to complain about your failure to do so.
>

> However, it seems most compilers make module variables
> SAVE by default....

I would not say that was accurately stated. Instead, I'd say that most
(all, to my knowledge) compilers implement modules in such a way that
unsaved variables act just like saved ones. The distinction is perhaps
nitpicky, but it does show up in things like you observed. The variables
don't actually have the SAVE attribute, which is why you get the
complaint. The standard requires the capbability for a compiler to
diagnose that problem. That requirement does not depend on whather
unsaved variables "might as well be saved" because they act the same for
all practical purposes. It depends on whether they have the SAVE
attribute.

> > As noted above, there is no "NULLIFY" in the code, but the default
> > initialization is fine as of f95, provided you use the SAVE attribute.
> > Default initialization was not a feature of the f90 standard at all; it
> > was one of the fairly few things introduced in f95.
>
> Hmm, I seem to have another gap in my knowledge here. Your remarks seems to
> indicate that there is a difference between a statement like:
> somepointer => NULL()
>
> and
> NULLIFY(somepointer)
>
> I know that "NULLIFY" can not be used for default initialization. But are
> there more differences?

As I mentioned in the part you elided, it is mostly a nitpick of
terminology, starting with the fact that you called the default
initialization a statement. It isn't. It is part of another statement.
"Statement" is a technical term in the language, and it is a term that
comes with a lot of "baggage", none of which really applies to the code
you had. For example, a statement can have a statement label. Lots more
like that. Hard for me to elaborate everything. It is sort of like you
had called it a subroutine. It just isn't one. You can write subroutines
that nullify pointers, and even subroutines that have NULLIFY statements
in them, but that doesn't mean an initialization or a NULLIFY statement
is a subroutine.

There is a pointer assignment statement that can look like

somepointer => NULL()

but initialization or default initialization do not involve that
statement. They use a syntax that looks like a restricted form of that
statement, but that doesn't mean they are that statement. Hard for me to
sit does and list the differences, particularly as many of them are so
trivial that it seem sto me that they aren't worth listing, but I can't
tell which ones you might have the same judgement about. The bit about
not allowing a statement label is pretty high on the list of "well duh"
differences that I'd guess you also would not really consider worth
mentioning, but other things are less obvious.

For example, you can use bounds remapping in a pointer assignment
statement, but not in an initialization. If this were not a pointer
case, a non-obvious difference would be that defined assignment never
applies to initializations; they always act like intrinsic assignment.
But default assignment doesn't apply to pointer assignment anyway.

And very relevant is that calling initialization a statement helps
confuse some people into thinking that it actually is an assignment
statement that just happens to be tacked onto the syntax of the type
declaration. This encourages confusions like the expectation that it
would be "executed" at the beginnning of each call to the subroutine;
after all, that's what would happen with an assignment statement.

Or perhaps you could just write it all off to me being a stickler for
terminology. Making sure that terminology was used correctly was part of
my job as editor of the standard. (Not that I did it perfectly, but it
was part of my job). It is important for a standard to say exactly what
it means instead of somnething that is "sort of simillar - enough so
that people ought to get the idea."

Phillip Helbig---undress to reply

unread,
Jun 12, 2012, 4:41:26 PM6/12/12
to
> > However, it seems most compilers make module variables
> > SAVE by default....
>
> I would not say that was accurately stated. Instead, I'd say that most
> (all, to my knowledge) compilers implement modules in such a way that
> unsaved variables act just like saved ones. The distinction is perhaps
> nitpicky, but it does show up in things like you observed. The variables
> don't actually have the SAVE attribute, which is why you get the
> complaint. The standard requires the capbability for a compiler to
> diagnose that problem. That requirement does not depend on whather
> unsaved variables "might as well be saved" because they act the same for
> all practical purposes. It depends on whether they have the SAVE
> attribute.

Another reason to heed warnings even if changing the code would mean no
changes for YOU is that it allows one to write more portable code. (I
say MORE portable since there are non-portable things which a compiler
is not required to catch.)

0 new messages