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

Fortran initialization

471 views
Skip to first unread message

Κώστας Ματαράς

unread,
Jan 9, 2021, 4:45:22 PM1/9/21
to
Is there a difference between initialization with declaration versus simple initialization?Why do i get different behavior?
For example :
recursive function foo(x) result (f)
real :: x , y = 0
real :: f
...
end function
!versus
recursive function foo(x) result (f)
real :: x , y
real :: f
y = 0
...
end function

steve kargl

unread,
Jan 9, 2021, 5:05:10 PM1/9/21
to
Yes, there is a difference. In your first example, the initialization
implies the SAVE attribute. The first call to 'foo' will initialize
'y' to zero. When 'foo' returns, the current value of 'y' is SAVEd.
The next invocation of 'foo' will then used the SAVEd value of y
for its starting value. In your second example, the value of 'y'
is assigned the value of zero each time you call foo.

--
steve

Κώστας Ματαράς

unread,
Jan 10, 2021, 6:49:00 AM1/10/21
to
Thought it would be something of the sort . Thanks!

Ron Shepard

unread,
Jan 10, 2021, 11:39:47 AM1/10/21
to
This has been controversial among fortran programmers since it was added
to the language (in F95, I think). Many of us would have preferred if,
instead of the implicit save, the language had required the SAVE
attribute to be required in the declaration+initialization statement,
with the compiler required to detect and notify the programmer when it
was not included. There is an equivalent situation with /DATA/
statements that should be treated consistently. That would have required
an extra five characters on such declarations, of course, but it would
have eliminated the confusion about this feature for the last 25 years
(and for the future, where it will continue to confuse programmers).

Of course, there is nothing that prevents the programmer from adding
those five extra characters now, ",save", to each such line. This is
what I recommend, and it is what I try to do with my own codes. This
makes both the programmer intent and the semantics clear and unambiguous.

Other ideas about the syntax+semantics of these cases have been proposed
too. However, it is unlikely at this point that the language will be
changed. There is too much existing code that uses the current rules
that would become incorrect if it were changed now, and backwards
compatibility is an important feature in the evolution of the fortran
language.

$.02 -Ron Shepard

Gary Scott

unread,
Jan 10, 2021, 1:29:09 PM1/10/21
to
I ALWAYS add 'save' explicitly, if that is the desired behavior. I
believe in explicitly identifying my intent in most cases. Programming
languages should be naturally conversational and clear, not with lots of
cryptic shortcuts.
>
> $.02 -Ron Shepard
>

baf

unread,
Jan 10, 2021, 1:53:07 PM1/10/21
to
It is likely that the confusion for many programmers is that the
initialization of y in the statement

real ::x , y = 0

only has an impact on the first entry into the function independent of
whether you use the save attribute or not.

Ron Shepard

unread,
Jan 10, 2021, 3:47:37 PM1/10/21
to
On 1/10/21 12:53 PM, baf wrote:
[...]
> It is likely that the confusion for many programmers is that the
> initialization of y in the statement
>
> real ::x , y = 0
>
> only has an impact on the first entry into the function independent of
> whether you use the save attribute or not.

Yes, that is why it is referred to as "implicit save" semantics. It
saves the programmer five characters of typing, but it causes decades of
confusion.

$.02 -Ron Shepard

gah4

unread,
Jan 10, 2021, 6:19:40 PM1/10/21
to
On Sunday, January 10, 2021 at 8:39:47 AM UTC-8, Ron Shepard wrote:

(snip)

> Of course, there is nothing that prevents the programmer from adding
> those five extra characters now, ",save", to each such line. This is
> what I recommend, and it is what I try to do with my own codes. This
> makes both the programmer intent and the semantics clear and unambiguous.

In the given case, though, SAVE only applies to y and not x.
If you put an actual SAVE on it, it would apply to both.

Maybe some day, though, they will allow for unSAVEd initialized
variables like many other languages.

Well, some languages don't have array constant expressions, but only array
initializers, so there is more need for initializing automatic variables.


Ron Shepard

unread,
Jan 11, 2021, 4:08:56 AM1/11/21
to
On 1/10/21 5:19 PM, gah4 wrote:
> On Sunday, January 10, 2021 at 8:39:47 AM UTC-8, Ron Shepard wrote:
>
> (snip)
>
>> Of course, there is nothing that prevents the programmer from adding
>> those five extra characters now, ",save", to each such line. This is
>> what I recommend, and it is what I try to do with my own codes. This
>> makes both the programmer intent and the semantics clear and unambiguous.
>
> In the given case, though, SAVE only applies to y and not x.
> If you put an actual SAVE on it, it would apply to both.
>
> Maybe some day, though, they will allow for unSAVEd initialized
> variables like many other languages.

That is one of the other possibilities that I mentioned previously. I am
opposed to adding that syntax to the language. It would make things even
more confusing than they already are, and it would be equivalent in
every possible way to a simple assignment statement, which of course is
already in the language.

$.02 -Ron Shepard

Robin Vowels

unread,
Jan 11, 2021, 5:54:31 AM1/11/21
to
On Monday, January 11, 2021 at 10:19:40 AM UTC+11, gah4 wrote:
> On Sunday, January 10, 2021 at 8:39:47 AM UTC-8, Ron Shepard wrote:
>
> (snip)
> > Of course, there is nothing that prevents the programmer from adding
> > those five extra characters now, ",save", to each such line. This is
> > what I recommend, and it is what I try to do with my own codes. This
> > makes both the programmer intent and the semantics clear and unambiguous.
> In the given case, though, SAVE only applies to y and not x.
> If you put an actual SAVE on it, it would apply to both.
>
> Maybe some day, though, they will allow for unSAVEd initialized
> variables like many other languages.

PL/I has both, with the specification of storage class -- STATIC or dynamic.

> Well, some languages don't have array constant expressions, but only array
> initializers, so there is more need for initializing automatic variables.

PL/I also allows storage class to be specified for arrays, so that an
initialization is possible as STATIC (constant values to be held in
static storage, and retained for subsequent entries) or automatic
(to be initialized every time the procedure is entered).

Robin Vowels

unread,
Jan 11, 2021, 5:56:11 AM1/11/21
to
Initialization via an assignment makes it absolutely clear that the
variable is initialized every time the procedure is entered.

gah4

unread,
Jan 11, 2021, 2:02:43 PM1/11/21
to
On Monday, January 11, 2021 at 1:08:56 AM UTC-8, Ron Shepard wrote:

(snip, I wrote)

> > Maybe some day, though, they will allow for unSAVEd initialized
> > variables like many other languages.

> That is one of the other possibilities that I mentioned previously. I am
> opposed to adding that syntax to the language. It would make things even
> more confusing than they already are, and it would be equivalent in
> every possible way to a simple assignment statement, which of course is
> already in the language.

In K&R C, you could only initialize static structures and arrays, not auto.
That makes some sense, as it has to store the initial values somewhere,
in addition to the variable itself. (On most systems, static initial values are
written directly into the object program.) I believe you could still initialize
auto non-struct scalars.

But ANSI C added initializers for auto struct and arrays.

There is a feature in Java and more recent versions of C, where you declare
a variable in a loop statement:

for(int i=0; i<10; i++) ...

As well as I know, the variable is still allocated on function entry, but has scope
of the loop, and using it outside the loop will generate a compile time error.
(Most often, I still do it the old way, though.)

Also, C and Java have array and struct initializers, but no array or struct constants
to assign outside initializers.

Since the Fortran default is SAVE, it would need a new keyword to override that,
which would make it somewhat obvious what you are doing.

Note also that initializing arrays in declarations or DATA statements tends
to make large object files, as all the values are written out. I learned this
in the Fortran 66 days, punching out an object program on cards.
Many cards were used to zero a large array, where zeroing with a DO
loop was small. Also, the DO loop is probably faster than reading
them from disk.

Thomas Koenig

unread,
Jan 11, 2021, 3:06:33 PM1/11/21
to
gah4 <ga...@u.washington.edu> schrieb:

> Maybe some day, though, they will allow for unSAVEd initialized
> variables like many other languages.

What's wrong with the construct

integer :: i
i = 42

?

Reminds me of the phrase used in

http://james-iry.blogspot.com/2009/05/brief-incomplete-and-mostly-wrong.html

"His lambda calculus is ignored because it is insufficiently
C-like. This criticism occurs in spite of the fact that C has not
yet been invented."

The same article, by the way, contains the golden words

"It is a syntax error to write FORTRAN while not wearing a blue tie."

Good thing we spell it Fortran now :-)

>

gah4

unread,
Jan 12, 2021, 2:54:15 AM1/12/21
to
On Monday, January 11, 2021 at 12:06:33 PM UTC-8, Thomas Koenig wrote:

(snip)
😂

my first try putting emoji's in posts, I hope it comes though.

dave_th...@comcast.net

unread,
Feb 28, 2021, 10:57:57 PM2/28/21
to
On Mon, 11 Jan 2021 11:02:40 -0800 (PST), gah4 <ga...@u.washington.edu>
wrote:
...
> There is a feature in Java and more recent versions of C, where you declare
> a variable in a loop statement:
>
> for(int i=0; i<10; i++) ...
>
Ada (in 83) also declares the loopvar in the loop only (and makes it
unwritable) but doesn't state the type which is implicit.

> As well as I know, the variable is still allocated on function entry, but has scope
> of the loop, and using it outside the loop will generate a compile time error.
> (Most often, I still do it the old way, though.)
>
In C the lifetime is defined only as loop; implementation must be 'as
if' the abstract semantics and can vary.

For Java bytecode, all local 'slots' used in the method are allocated
at entry, but if you do e.g.

void mymeth (int x, double y){
for( int i = 0; i < 10; i++ ) { /*nothing*/ }
{ float z = 3.4; System.out.println (z); }
}

both i and z use local slot 4 at different times, so is it allocated
to either one, both, or neither? ('this' is slot 0 for a nonstatic
method, x is slot 1, and y is slots 2 and 3; 64-bit values use two
slots even on a 64-bit JVM because bytecode doesn't know bitness).

When JITted it's up to the compiler how/when things are allocated.

> Also, C and Java have array and struct initializers, but no array or struct constants
> to assign outside initializers.
>
C does since C99, the same version that added for(decl;test;step) .
Java doesn't have class 'constants' anywhere (only constructor calls);
it doesn't exactly have array constants, but can construct an array
from a list of values anywhere using e.g.

new float[] { 1.2f, 3.4f, 5.6f }

and only in a declaration/initializer you can omit the 'new T[]' (but
the semantics of calling newarray is the same as if you did write it).

> Since the Fortran default is SAVE, it would need a new keyword to override that,
> which would make it somewhat obvious what you are doing.
>
I have tried to promote SPEND or DAMN as the opposite to SAVE, but
without success :-)

JCampbell

unread,
Mar 2, 2021, 11:06:40 PM3/2/21
to
I don't find it controversial.
Prior to F90, there were data statements that had the same effect.
Many "first call" approaches rely on the difference between "real :: y = 0" and "real :: y ; y = 0"

Ron Shepard

unread,
Mar 3, 2021, 3:02:48 AM3/3/21
to
In F77, if a data statement was used to initialize an unsaved local
variable, and if that value was changed during execution, then its value
on subsequent entry to that subprogram was undefined. It was only if the
value was unchanged during execution that its value was defined to have
that same value upon subsequent entry to that subprogram. I assume that
undefined nature was a carryover from the earlier f66 standard -- I do
not think that was introduced just in f77, otherwise it would have
changed existing legal code to be illegal.

$.02 -Ron Shepard


gah4

unread,
Mar 3, 2021, 6:03:42 AM3/3/21
to
On Wednesday, March 3, 2021 at 12:02:48 AM UTC-8, Ron Shepard wrote:

(snip on SAVE and initialization)

> > I don't find it controversial.
> > Prior to F90, there were data statements that had the same effect.
> > Many "first call" approaches rely on the difference between "real :: y = 0" and "real :: y ; y = 0"
> In F77, if a data statement was used to initialize an unsaved local
> variable, and if that value was changed during execution, then its value
> on subsequent entry to that subprogram was undefined. It was only if the
> value was unchanged during execution that its value was defined to have
> that same value upon subsequent entry to that subprogram. I assume that
> undefined nature was a carryover from the earlier f66 standard -- I do
> not think that was introduced just in f77, otherwise it would have
> changed existing legal code to be illegal.

As well as I know it, f66 has it undefined to allow for overlays, and f77 to
allow for automatic allocation.

From the beginning, Fortran used static allocation but, as far as I know,
never said that anywhere. I am not so sure when overlays came along,
but were reasonably common by f66 times.

By f77, many systems used automatic allocation. As noted, the f66
rules were not incompatible with it, and SAVE was added.

JCampbell

unread,
Mar 3, 2021, 6:41:38 AM3/3/21
to
The functionality of data/save variables has been required for the random number generators that I written in FORTRAN and have used. I can't recall using a compiler that did not support this functionality.
My recollection is that DATA implied a saved variable in all F77 compilers I used on PC, Apollo/Sun and Pr1me/Vax.
Those I used all supported a first call approach and retained the value, implied by the use of a DATA statement. There were many other F77 compilers I did not use.
It is difficult to remember any F77 compilers that performed different to as I recall. (ICL or IBM ?)
I did use Lahey LF77 Fortran (640k) with an overlay linker. The retention of saved variables may have depended if the routine went out of scope, although the linker could have retained all static variables in scope. The days of reviewing the load map !!
Ron, what compilers have you used that suggest the controversy ?
The concept that "otherwise it would have changed existing legal code to be illegal" was not as strictly interpreted prior to F90/95 as most compilers had their own extensions.
Portability was a big issue prior to F90 which was a significant success of F90.
Am I correct to assume that F90+ standard supports the "first call" difference between "real :: y = 0" and "real :: y ; y = 0" ?

Ron Shepard

unread,
Mar 3, 2021, 12:19:58 PM3/3/21
to
On 3/3/21 5:41 AM, JCampbell wrote:
> On Wednesday, March 3, 2021 at 10:03:42 PM UTC+11, gah4 wrote:
>> On Wednesday, March 3, 2021 at 12:02:48 AM UTC-8, Ron Shepard wrote:
>>
>> (snip on SAVE and initialization)
>>>> I don't find it controversial.
>>>> Prior to F90, there were data statements that had the same effect.
>>>> Many "first call" approaches rely on the difference between "real :: y = 0" and "real :: y ; y = 0"
>>> In F77, if a data statement was used to initialize an unsaved local
>>> variable, and if that value was changed during execution, then its value
>>> on subsequent entry to that subprogram was undefined. It was only if the
>>> value was unchanged during execution that its value was defined to have
>>> that same value upon subsequent entry to that subprogram. I assume that
>>> undefined nature was a carryover from the earlier f66 standard -- I do
>>> not think that was introduced just in f77, otherwise it would have
>>> changed existing legal code to be illegal.
>> As well as I know it, f66 has it undefined to allow for overlays, and f77 to
>> allow for automatic allocation.
>>
>> From the beginning, Fortran used static allocation but, as far as I know,
>> never said that anywhere. I am not so sure when overlays came along,
>> but were reasonably common by f66 times.
>>
>> By f77, many systems used automatic allocation. As noted, the f66
>> rules were not incompatible with it, and SAVE was added.
>
> The functionality of data/save variables has been required for the random number generators that I written in FORTRAN and have used.

If so, then you were depending on the behavior of a specific compiler,
not on the semantics specified by the language standard. The standard
conforming way to "save" a variable before f77 was to put it in a common
block. It was not uncommon to see named common blocks with single
variables in them, often with oddball names in the attempt to avoid
linker symbol conflicts, to save the values of variables that were
otherwise local. f77 introduced SAVE, which could be used for either
common blocks or for local variables, and that allowed many
nonconforming dusty deck codes that relied on static variables to be
modified and to become standard conforming. But for the present
discussion, f77 did not have "automatic save" of any variables, whether
associated with DATA statements or not. Even common blocks were allowed
to go out of scope in f77 if they were not saved. The SAVE attribute had
to be specified explicitly to be conforming.

> I can't recall using a compiler that did not support this functionality.

Yes, I know. It was not uncommon to depend on static allocation of
variables or of common blocks, especially before f77, but also
afterwards with dusty deck code. But that behavior was not required by
the f66 standard, and f77 introduced SAVE specifically for that purpose.

> My recollection is that DATA implied a saved variable in all F77 compilers I used on PC, Apollo/Sun and Pr1me/Vax.

Yes, likely all variables were static in those compilers, but it was not
required by the standard.

> Those I used all supported a first call approach and retained the value, implied by the use of a DATA statement. There were many other F77 compilers I did not use.
> It is difficult to remember any F77 compilers that performed different to as I recall. (ICL or IBM ?)

If you used an overlay linker, then you could have several copies of a
named common block or of a subroutine with its own local variables, each
with its own set of saved values. I experimented enough to do that a few
times and get things to work, but when I was writing code designed to
run on more than one machine, I avoided doing it.

> I did use Lahey LF77 Fortran (640k) with an overlay linker. The retention of saved variables may have depended if the routine went out of scope, although the linker could have retained all static variables in scope. The days of reviewing the load map !!
> Ron, what compilers have you used that suggest the controversy ?

You are mistaken about what the controversy is. The controversy is the
introduction of implied save, which I think occurred in f95. Many
programmers, myself included, would have preferred that the SAVE
attribute be required for initialized variables, and also that the
compiler would have been required to diagnose the missing SAVE attribute
and warn the programmer (at compile time, not run time).

> The concept that "otherwise it would have changed existing legal code to be illegal" was not as strictly interpreted prior to F90/95 as most compilers had their own extensions.
> Portability was a big issue prior to F90 which was a significant success of F90.
> Am I correct to assume that F90+ standard supports the "first call" difference between "real :: y = 0" and "real :: y ; y = 0" ?


I'm not certain, but I think f90 left the situation undefined, the same
as f77, but now extended also to initialization on the declaration line
which was the new syntax. in other words, the value on subsequent entry
to the subprogram was only defined when it had not been changed during
previous executions. Then f95 introduced the implied save, which, as we
can see by this discussion, has been a confusing feature for some 25
years, and will continue to be a confusing feature in the future,
especially now that all subroutines have also an implied RECURSIVE
attribute. As I said previously, I do not think that feature will ever
be changed because it would now invalidate too much existing code that
depends on implied save. At this point, I regard it as a mistake in the
language that we all must continue to tolerate indefinitely and to
discuss endlessly.

$.02 -Ron Shepard

gah4

unread,
Mar 3, 2021, 3:13:35 PM3/3/21
to
On Wednesday, March 3, 2021 at 3:41:38 AM UTC-8, JCampbell wrote:

(snip, I wrote)
> > From the beginning, Fortran used static allocation but, as far as I know,
> > never said that anywhere. I am not so sure when overlays came along,
> > but were reasonably common by f66 times.

> > By f77, many systems used automatic allocation. As noted, the f66
> > rules were not incompatible with it, and SAVE was added.

> The functionality of data/save variables has been required for the random number
> generators that I written in FORTRAN and have used. I can't recall using a
> compiler that did not support this functionality.

Until f77, compilers tended to use static data, users expected it, and so
compiler writers supplied it. For one, it was usually faster.
Languages with recursion supplied automatic data, as that is
pretty much required.

> My recollection is that DATA implied a saved variable in all F77
> compilers I used on PC, Apollo/Sun and Pr1me/Vax.

The complication is that overlay is supplied by the linker, maybe
separate from the compiler writers. Overlay linkers that I remember
put things into the root segment unless you moved them. Others
might not have done that. RNG were small, so that would not have
been a problem.

> Those I used all supported a first call approach and retained the value,
> implied by the use of a DATA statement. There were many other F77
> compilers I did not use.

Well, also, it was usual for static data to be together with code.
In IBM terms, in the same CSECT. Usually all variables following
the code, and addressed the same way.

When cache started to be used, and especially separate instruction
and data cache, that turned out to be bad. On many systems, things
can't be in both instruction and data cache at the same time, and have
to be far enough apart in memory.

> It is difficult to remember any F77 compilers that performed different to as I recall. (ICL or IBM ?)
> I did use Lahey LF77 Fortran (640k) with an overlay linker.
> The retention of saved variables may have depended if the routine went out of scope,
> although the linker could have retained all static variables in scope.
> The days of reviewing the load map !!

That was about the time that separating code and data started to be a thing.
Also, for x86 code, with code and data segments that could be separate.

> Ron, what compilers have you used that suggest the controversy ?
> The concept that "otherwise it would have changed existing legal code to be illegal"
> was not as strictly interpreted prior to F90/95 as most compilers had their own extensions.

Well, yes, but compilers could be known for not following unwritten rules
that other compilers followed. The one-trip DO loop being a common case.
The standard never said that, even the non-standard never did, but compilers
implemented it and users expected it.

> Portability was a big issue prior to F90 which was a significant success of F90.
> Am I correct to assume that F90+ standard supports the "first call"
> difference between "real :: y = 0" and "real :: y ; y = 0" ?

I don't know about "first call", but the former is static allocated, and the latter
(however allocated) assigned every time. The usual implementation of static
data is that it is written into the object module. It happens when the program
is loaded into memory.

By the way, because of the way static memory is initialized, you can get
very large object programs and large load modules. Many now don't
store zeros, but non-zero values will be written out, even large arrays
full of them.

real:: y(10000000) = 1

can generate a very large object program!

gah4

unread,
Mar 3, 2021, 3:19:58 PM3/3/21
to
On Wednesday, March 3, 2021 at 9:19:58 AM UTC-8, Ron Shepard wrote:
(big snip)

>. Then f95 introduced the implied save, which, as we
> can see by this discussion, has been a confusing feature for some 25
> years, and will continue to be a confusing feature in the future,
> especially now that all subroutines have also an implied RECURSIVE
> attribute. As I said previously, I do not think that feature will ever
> be changed because it would now invalidate too much existing code that
> depends on implied save. At this point, I regard it as a mistake in the
> language that we all must continue to tolerate indefinitely and to
> discuss endlessly.

Yes existing code won't change, but a new keyword to allow for initialized
automatic data could be added. As above, SPEND and DAMN are two possible
opposites of SAVE.

Ron Shepard

unread,
Mar 4, 2021, 3:57:36 AM3/4/21
to
Well, first, that functionality already exists in the language, so
adding those new keywords is only syntax sugar with a redundant
aftertaste. Redundancy is not necessarily a bad thing, and different
programmers have different preferences.

Second, those keywords do not solve the problem that implied save
causes. Namely, that variables are saved without it being obvious to the
programmer. Now that RECURSIVE is implied, this also means that
modifying those variables in one invocation of a routine also modifies
those values in subsequent direct or indirect invocations, and visa
versa, whereas the true automatic local variables in those invocations
are all fresh copies.

I would still like the compiler to warn me when implied SAVE has been
invoked, just to make sure I know what is happening and that I intend
that behavior to occur. Of course, the first action I would take in
those cases would be to add SAVE explicitly to the declaration in order
to get rid of those warnings since that is my preferred style anyway.

$.02 -Ron Shepard

gah4

unread,
Mar 4, 2021, 7:29:11 AM3/4/21
to
On Thursday, March 4, 2021 at 12:57:36 AM UTC-8, Ron Shepard wrote:

(snip, I wrote)
> > Yes existing code won't change, but a new keyword to allow for initialized
> > automatic data could be added. As above, SPEND and DAMN are two possible
> > opposites of SAVE.

> Well, first, that functionality already exists in the language, so
> adding those new keywords is only syntax sugar with a redundant
> aftertaste. Redundancy is not necessarily a bad thing, and different
> programmers have different preferences.

For scalars it is easy, not so easy for arrays of unknown size.

REAL, AUTO :: X(:) = {1., 2., 3.}

If you do for example, which is not unusual in C:

REAL, AUTO :: X(:) = {&
#include "init.h"
}

there isn't a convenient way to size the array.

I suppose one could do an allocate on assignment ALLOCATABLE
array, but the question is for an auto array.

I suspect ALLOCATABLE is less efficient, though that might not
be a convincing reason not to use it.


> Second, those keywo rds do not solve the problem that implied save

Ron Shepard

unread,
Mar 4, 2021, 12:24:19 PM3/4/21
to
On 3/4/21 6:29 AM, gah4 wrote:
> On Thursday, March 4, 2021 at 12:57:36 AM UTC-8, Ron Shepard wrote:
>
> (snip, I wrote)
>>> Yes existing code won't change, but a new keyword to allow for initialized
>>> automatic data could be added. As above, SPEND and DAMN are two possible
>>> opposites of SAVE.
>
>> Well, first, that functionality already exists in the language, so
>> adding those new keywords is only syntax sugar with a redundant
>> aftertaste. Redundancy is not necessarily a bad thing, and different
>> programmers have different preferences.
>
> For scalars it is easy, not so easy for arrays of unknown size.
>
> REAL, AUTO :: X(:) = {1., 2., 3.}
>
> If you do for example, which is not unusual in C:
>
> REAL, AUTO :: X(:) = {&
> #include "init.h"
> }
>
> there isn't a convenient way to size the array.
>
> I suppose one could do an allocate on assignment ALLOCATABLE
> array, but the question is for an auto array.
>
> I suspect ALLOCATABLE is less efficient, though that might not
> be a convincing reason not to use it.

I don't know your exact application, but something like

real :: x(size(whatever))
...
x = whatever

defines correctly the size of the automatic array and then initializes
it on each entry to the subprogram. "whatever" needs to be a dummy
argument, module array, or host associated, it can't be a general
expression in the declaration, so it is limited in that way.

As for the inability to initialize allocatable arrays, I agree with that
criticism. That would be a wonderful feature to add to the language.

$.02 -Ron Shepard

gah4

unread,
Mar 4, 2021, 3:42:56 PM3/4/21
to
On Thursday, March 4, 2021 at 9:24:19 AM UTC-8, Ron Shepard wrote:

(snip, I wrote)

> > REAL, AUTO :: X(:) = {1., 2., 3.}

(snip)

> I don't know your exact application, but something like

> real :: x(size(whatever))
> ...
> x = whatever

REAL :: X(size({1., 2., 3.} ))
x={1., 2., 3.}

If the array has many elements it gets ugly looking.
I presume it goes the count at compile time and doesn't keep around the
first copy of the constants.

REAL :: X(size({ &
#include "init.h"
})

x={&
#include "init.h"
}

I suppose it works.

Also, C and Java allow a trailing comma on initializer lists, which is convenient not to
have to special-case the last one.

static double a[]={
#ifdef X
#include "X.h"
#endif
#ifdef Y
#include "Y.h"
#endif
#ifdef Z
#include "Z.h"
#endif
};

each one has a trailing comma, and any can be the last one.

The tradition of Unix is that there is an array of struct that is the core of the I/O
system, generated at sysgen time based on the I/O devices that are included.
For many years, this meant that a Unix system had to come with a C compiler,
for the ability to do a sysgen. (Maybe only for that one file.)

At some point, Sun unbundled the C compiler, with a much reduced
version included with the OS. That might have increased interest
in gcc at the time, when otherwise the included C compiler might
have been good enough.

Robin Vowels

unread,
Mar 5, 2021, 9:26:52 AM3/5/21
to
On Wednesday, March 3, 2021 at 10:03:42 PM UTC+11, gah4 wrote:
.
Overlays were common from the 1950s, when memories were
relatively small.

Themos Tsikas

unread,
Mar 5, 2021, 12:59:27 PM3/5/21
to
On Thursday, 4 March 2021 at 20:42:56 UTC, gah4 wrote:
...
>
> If the array has many elements it gets ugly looking.
> I presume it goes the count at compile time and doesn't keep around the
> first copy of the constants.
>
> REAL :: X(size({ &
> #include "init.h"
> })
>
> x={&
> #include "init.h"
> }
>
> I suppose it works.
>

Doesn't this work for you :

REAL, PARAMETER :: XP(*) = [ &
#include "init.h"
]

REAL :: X(SIZE(XP)) = XP

Themos Tsikas, NAG Ltd

gah4

unread,
Mar 5, 2021, 1:48:35 PM3/5/21
to
On Friday, March 5, 2021 at 9:59:27 AM UTC-8, Themos Tsikas wrote:

(snip, I wrote)

> > REAL :: X(size({ &
> > #include "init.h"
> > })

> > x={&
> > #include "init.h"
> > }


> Doesn't this work for you :

> REAL, PARAMETER :: XP(*) = [ &
> #include "init.h"
> ]

> REAL :: X(SIZE(XP))


Except that the latter has to be:

REAL :: X(SIZE(XP))

X = XP

because the whole idea is not to SAVE X,
but yes that is probably a better way.


Robin Vowels

unread,
Mar 6, 2021, 5:56:19 AM3/6/21
to
On Saturday, March 6, 2021 at 4:59:27 AM UTC+11, Themos Tsikas wrote:
> On Thursday, 4 March 2021 at 20:42:56 UTC, gah4 wrote:
> ...
> >
> > If the array has many elements it gets ugly looking.
> > I presume it goes the count at compile time and doesn't keep around the
> > first copy of the constants.
> >
> > REAL :: X(size({ &
> > #include "init.h"
> > })
> >
> > x={&
> > #include "init.h"
> > }
> >
> > I suppose it works.
> >
> Doesn't this work for you :
>
> REAL, PARAMETER :: XP(*) = [ &
> #include "init.h"
> ]
.
what is that supposed to do?
.
> REAL :: X(SIZE(XP)) = XP

Ev. Drikos

unread,
Mar 6, 2021, 8:42:31 AM3/6/21
to
On 04/03/2021 22:42, gah4 wrote:
> ...
> REAL :: X(size({1., 2., 3.} ))

> ...
> Also, C and Java allow a trailing comma on initializer lists, which is convenient not to
> have to special-case the last one.
>
> ...

A trailing comma can also be a convenience for a tool than exports (or
generates) data based on some template, ie line by line. Maintaining a
a distinct last line in such templates could be cumbersome.

IMHO however, the number of the tuples (ie the size above) is computed
easily in such cases and the developer of such a tool would normally
expect that the declaration may be far away from the assignment(s). It
is of course just a subjective opinion based on my limited experience.


Ev. Drikos

Ev. Drikos

unread,
Mar 6, 2021, 12:01:36 PM3/6/21
to
On 06/03/2021 15:42, Ev. Drikos wrote:
> On 04/03/2021 22:42, gah4 wrote:
>> ...
>> REAL :: X(size({1., 2., 3.} ))
>
>> ...
>> Also, C and Java allow a trailing comma on initializer lists, which is
>> convenient not to
>> have to special-case the last one.
>>
>> ...
>
> A trailing comma can also be a convenience for a tool than exports (or
> generates) data based on some template, ie line by line. Maintaining a
> a distinct last line in such templates could be cumbersome.
> ...
Oh, another possibility in my case, could be a redundant line at the end
of a table, possibly filled with some neutral values (ie "0,0,0 };").

But I think you made a good point, the trailing comma is much better.

Ev. Drikos

gah4

unread,
Mar 6, 2021, 3:13:11 PM3/6/21
to
On Saturday, March 6, 2021 at 9:01:36 AM UTC-8, Ev. Drikos wrote:
> On 06/03/2021 15:42, Ev. Drikos wrote:
> > On 04/03/2021 22:42, gah4 wrote:

(snip)

> >> Also, C and Java allow a trailing comma on initializer lists, which is
> >> convenient not to
> >> have to special-case the last one.

> > A trailing comma can also be a convenience for a tool than exports (or
> > generates) data based on some template, ie line by line. Maintaining a
> > a distinct last line in such templates could be cumbersome.

In the case of C, it is somewhat usual to do it with #ifdef based on
defined symbols. I believe that is the way the traditional Unix I/O
system worked. (As well as I know, not anymore.)

It is, then, much harder to figure out which is the last one.

> Oh, another possibility in my case, could be a redundant line at the end
> of a table, possibly filled with some neutral values (ie "0,0,0 };").

Since all Unix systems have a /dev/null, it would be convenient, but
I believe it is supposed to be device zero.

OK, I haven't done, or even thought about doing, Unix-style sysgen
for some years. It seems on the machines I now have /dev/null
is not device (major number) 0. But then again, I don't think they
use the same static sysgen-defined struct anymore. Next time
I run one of those old systems, I will have to check.
0 new messages