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

gfortran rhs reallocation

86 views
Skip to first unread message

Athanasios Migdalas

unread,
Feb 24, 2012, 9:47:55 PM2/24/12
to
Hi all.

Consider this
REAL, ALLOCATABLE :: v(:)

:
v = (/ v, 1, 2, 3, 4, 5/)


Gfortran version 4.6.3 20120127 (prerelease) marks the assignment as error
because the constants ara integers and not reals:


Error: Element in REAL(4) array constructor at (1) is INTEGER(4)

The assignment would have been accepted once rewritten as


v = (/ v, 1., 2., 3., 4., 5./)

Is this so according to the standard or is Gfortran too stringent here? I
cannot deduce what is the case from Metcalf et al «Fortran explained».

Can anybody be of assistance?

Thank you in advance,

/Sakis


--
A.M.

Dick Hendrickson

unread,
Feb 24, 2012, 10:20:05 PM2/24/12
to
There is a constraint that applies to array constructors

"C494 (R466) If type-spec is omitted, each ac-value expression in the
array-constructor shall have the same type and kind type parameters."

So, Gfortran is correct. You could do something like
(/ real:: v, 1, 2, 3.0, 4.0d0, 5 /)

each operand in the list must be assignment compatible with the
specified type (real here).

Dick Hendrickson

Richard Maine

unread,
Feb 24, 2012, 10:33:45 PM2/24/12
to
Dick Hendrickson <dick.hen...@att.net> wrote:

> On 2/24/12 8:47 PM, Athanasios Migdalas wrote:
> > Hi all.
> >
> > Consider this
> > REAL, ALLOCATABLE :: v(:)
> >
> > :
> > v = (/ v, 1, 2, 3, 4, 5/)

> "C494 (R466) If type-spec is omitted, each ac-value expression in the
> array-constructor shall have the same type and kind type parameters."

And note that this really has norhing to do with being allocatable or on
the rhs of an assignment. It is a constraint on array constructors in
general. Without some kind of constraint, it can get really tricky to
determine what the type and kind of the array constructor is supposed to
be. SImple solutions like taking the type and kind of the first element
are *NOT* as simple as one might think in all cases. Yes, it takes some
trickery to come up with the truly messy cases. There were a lot of
attempts to relax the constrints, but the relaxations always turned out
to make it possible to write something with "unfortunate" consequences.
Eventually, it was mostly punted.

I know that if I try to come up with examples of the problems, someone
will propose a solution that looks like it works. But I'll pretty much
guarantee that the solution won't work for all cases. The committee
spent a lot of time iterating on that kind of thing, thinking there was
a solution that worked, only to have someone blow a hole in it at the
next meeting.

--
Richard Maine
email: last name at domain . net
domain: summer-triangle

Dick Hendrickson

unread,
Feb 25, 2012, 11:49:41 AM2/25/12
to
Ahh, Richard. This brings back happy memories of why standards are so
much fun.

One of the killers is something like

(/ (1,I=1,n), ('abc', I = 1,m), real_array /)

integer, character or real? Sort of depends on the values of n, m, and
size(real_array). And it's a real bugger if more than one is non-zero
or all three are zero.

Dick Hendrickson

Athanasios Migdalas

unread,
Feb 25, 2012, 7:50:29 PM2/25/12
to
Thank you Dick & Richard, and yes I have encountered just today that
gfortran will complain for array constructors not being of the correct type.
Actually I was surprised because I was expecting it to auto cast the
integers to reals. Actually one other compiler I tested silently does that.
But now I know who follows the standard.

Thanks

/Sakis
--
A.M.

Richard Maine

unread,
Feb 25, 2012, 8:07:41 PM2/25/12
to
Athanasios Migdalas <sam...@gmail.com> wrote:

> Thank you Dick & Richard, and yes I have encountered just today that
> gfortran will complain for array constructors not being of the correct type.
> Actually I was surprised because I was expecting it to auto cast the
> integers to reals. Actually one other compiler I tested silently does that.
> But now I know who follows the standard.

It should cast them to reals if you tell it that's what you want, as
DIck showed earlier. Use the form (new to f2003)

[real:: v, 1, 2, 3, 4, 5]

The problem without the "real::" part is that it doesn't know what to
cast to what. For example, why wouldn't it cast the reals to integers
instead of the integers to reals? Just giving "preference" to the first
element (the kind of rule that people tried to write) doesn't always
work out.

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

Robin Vowels

unread,
Feb 28, 2012, 1:22:31 AM2/28/12
to
On Feb 25, 2:20 pm, Dick Hendrickson <dick.hendrick...@att.net> wrote:
> On 2/24/12 8:47 PM, Athanasios Migdalas wrote:
>
>
>
> > Hi all.
>
> > Consider this
> > REAL, ALLOCATABLE :: v(:)
>
> > :
> > v = (/ v, 1, 2, 3, 4, 5/)
>
> > Gfortran version 4.6.3 20120127 (prerelease) marks the assignment as error
> > because the constants ara integers and not reals:
>
> > Error: Element in REAL(4) array constructor at (1) is INTEGER(4)
>
> > The assignment would have been accepted once rewritten as
>
> > v = (/ v, 1., 2., 3., 4., 5./)
>
> > Is this so according to the standard or is Gfortran too stringent here? I
> > cannot deduce what is the case from Metcalf et al «Fortran explained».
>
> > Can anybody be of assistance?
>
> > Thank you in advance,
>
> > /Sakis
>
> There is a constraint that applies to array constructors
>
> "C494 (R466) If type-spec is omitted, each ac-value expression in the
> array-constructor shall have the same type and kind type parameters."
>
> So, Gfortran is correct.  You could do something like
>        (/ real::  v, 1, 2, 3.0, 4.0d0, 5 /)

Alternatively, it can be written as

v = (/ v, real( (/ 1, 2, 3, 4, 5 /) ) /)

Robin Vowels

unread,
Feb 28, 2012, 1:29:56 AM2/28/12
to
On Feb 25, 2:33 pm, nos...@see.signature (Richard Maine) wrote:
> Dick Hendrickson <dick.hendrick...@att.net> wrote:
> > On 2/24/12 8:47 PM, Athanasios Migdalas wrote:

> > > Consider this
> > > REAL, ALLOCATABLE :: v(:)
>
> > > :
> > > v = (/ v, 1, 2, 3, 4, 5/)
> > "C494 (R466) If type-spec is omitted, each ac-value expression in the
> > array-constructor shall have the same type and kind type parameters."
>
> And note that this really has norhing to do with being allocatable or on
> the rhs of an assignment. It is a constraint on array constructors in
> general. Without some kind of constraint, it can get really tricky to
> determine what the type and kind of the array constructor is supposed to
> be. SImple solutions like taking the type and kind of the first element
> are *NOT* as simple as one might think in all cases. Yes, it takes some
> trickery to come up with the truly messy cases. There were a lot of
> attempts to relax the constrints, but the relaxations always turned out
> to make it possible to write something with "unfortunate" consequences.
> Eventually, it was mostly punted.

It shouldn't have been difficult to resolve.
If the values are numeric, then if there's one or more REALs,
then the constructor is promoted to REAL (the longest of the presented
kinds), otherwise it's integer.

It's something that was resolved 45+ years when PL/I
was designed.

Robin Vowels

unread,
Feb 28, 2012, 1:43:02 AM2/28/12
to
On Feb 26, 12:07 pm, nos...@see.signature (Richard Maine) wrote:
> Athanasios Migdalas <sami...@gmail.com> wrote:
> > Thank you Dick & Richard, and yes I have encountered just today that
> > gfortran will complain for array constructors not being of the correct type.
> > Actually I was surprised because I was expecting it to auto cast the
> > integers to reals. Actually one other compiler I tested silently does that.
> > But now I know who follows the standard.
>
> It should cast them to reals if you tell it that's what you want, as
> DIck showed earlier. Use the form (new to f2003)
>
>   [real:: v, 1, 2, 3, 4, 5]
>
> The problem without the "real::" part is that it doesn't know what to
> cast to what. For example, why wouldn't it cast the reals to integers
> instead of the integers to reals?

Why on earth would it do that. Converting REALs to INTEGERs
would be plain silly, even perverse, and would usually result in loss
of information through truncation of any fractional parts.

> Just giving "preference" to the first
> element (the kind of rule that people tried to write) doesn't always
> work out.

A constructor containing numeric values could default to integer
when all the constants etc within it are integer;
otherwise it could default to REAL (of the longest kind).

Conversions of this kind were resolved some 45 years ago
when PL/I was designed.

Tobias Burnus

unread,
Feb 28, 2012, 2:12:09 AM2/28/12
to
Robin Vowels wrote:
> It shouldn't have been difficult to resolve.
> If the values are numeric, then if there's one or more REALs,
> then the constructor is promoted to REAL (the longest of the presented
> kinds), otherwise it's integer.
>
> It's something that was resolved 45+ years when PL/I
> was designed.

Okay, how do you resolve the equivalent to the following in PL/I?

function char_returning_function(str)
character(len=:), allocatable :: char_returning_function
allocate(character(len=20) :: char_returning_function)
char_returning_function = 'ABC'
end function

subroutine example(n, a, b)
integer :: n
character(len=n) :: a
character(len=*) :: b
character(len=:), allocatable :: c(:)
c = [a, b, [ "abcd", a//b ]//"ab" // a, char_returning_function(b)]
end subroutine

I am not claiming that it is impossible to solve, but it is surely not
trivial to do so and definitely not possible at compile time. I am sure
that one can dream up even more complicated examples.

While using a type-spec such as
c = [ character(len=20*n) :: a, b, &
[ "abcd", a//b ]//"ab" // a, char_returning_function(b)]
makes life much easier for compiler writers.

Tobias

Robin Vowels

unread,
Feb 28, 2012, 3:57:01 AM2/28/12
to
On Feb 28, 6:12 pm, Tobias Burnus <bur...@net-b.de> wrote:
> Robin Vowels wrote:
> > It shouldn't have been difficult to resolve.
> > If the values are numeric, then if there's one or more REALs,
> > then the constructor is promoted to REAL (the longest of the presented
> > kinds), otherwise it's integer.
>
> > It's something that was resolved 45+ years when PL/I
> > was designed.
>
> Okay, how do you resolve the equivalent to the following in PL/I?
>
> function char_returning_function(str)
>    character(len=:), allocatable :: char_returning_function
>    allocate(character(len=20) :: char_returning_function)
>    char_returning_function = 'ABC'
> end function
>
> subroutine example(n, a, b)
>    integer :: n
>    character(len=n) :: a
>    character(len=*) :: b
>    character(len=:), allocatable :: c(:)
>    c = [a, b, [ "abcd", a//b ]//"ab" // a, char_returning_function(b)]
> end subroutine
>
> I am not claiming that it is impossible to solve, but it is surely not
> trivial to do so and definitely not possible at compile time.

Definitely not possible to do what?
Generate the code to call the function?
The catenations?

The constructor list is clearly an array of characters.
It's not even a mixture of types, which is what others were worring
about.

> I am sure
> that one can dream up even more complicated examples.
>
> While using a type-spec such as
>    c = [ character(len=20*n) :: a, b, &
>          [ "abcd", a//b ]//"ab" // a, char_returning_function(b)]
> makes life much easier for compiler writers.

How? The constructor list already consists of character expressions.

In answer to your specific question:

declare c(5) character (32000) varying initial (
a, b, 'abcd'||'ab'||a, a||b||'ab'||a, char_returning_function(b) );

glen herrmannsfeldt

unread,
Feb 28, 2012, 4:33:19 AM2/28/12
to
In comp.lang.fortran Robin Vowels <robin....@gmail.com> wrote:

(snip)
>> It should cast them to reals if you tell it that's what you want, as
>> DIck showed earlier. Use the form (new to f2003)

>> [real:: v, 1, 2, 3, 4, 5]

>> The problem without the "real::" part is that it doesn't know what to
>> cast to what. For example, why wouldn't it cast the reals to integers
>> instead of the integers to reals?

> Why on earth would it do that. Converting REALs to INTEGERs
> would be plain silly, even perverse, and would usually result in loss
> of information through truncation of any fractional parts.

Last I knew, PL/I and C allowed for array initializers, but
nothing like Fortran array constructors.

But PL/I allows for structure expressions, so there would
be use for such in PL/I.

> A constructor containing numeric values could default to integer
> when all the constants etc within it are integer;
> otherwise it could default to REAL (of the longest kind).

> Conversions of this kind were resolved some 45 years ago
> when PL/I was designed.

DCL 1 STRUCT,
2 I FIXED BIN(31,0),
2 J FIXED DEC(10,0),
2 F FLOAT BIN(24),
2 G FLOAT DEC(15);

Now, what value do you assign to STRUCT in an assignment statement?

If PL/I had constructors, one could:

STRUCT = [ 1, 2.0, 3.1, 4 ];


You can, though, assign a constant:

STRUCT = 3;

or use it in an expression:

STRUCT = SQRT(STRUCT);

-- glen

Tobias Burnus

unread,
Feb 28, 2012, 6:03:11 AM2/28/12
to
On 02/28/2012 09:57 AM, Robin Vowels wrote:
> On Feb 28, 6:12 pm, Tobias Burnus<bur...@net-b.de> wrote:
>> Robin Vowels wrote:
>>> It's something that was resolved 45+ years when PL/I
>>> was designed.

>> Okay, how do you resolve the equivalent to the following in PL/I?
>>
>> c = [a, b, [ "abcd", a//b ]//"ab" // a, char_returning_function(b)]
>>
>> I am not claiming that it is impossible to solve, but it is surely not
>> trivial to do so and definitely not possible at compile time.
>
> Definitely not possible to do what?
> Generate the code to call the function?
> The catenations?

The point is: What's the length-type parameter of the array constructor?
By itself, it is not obvious as there are at the end 5 array elements,
which (might) have all different lengths.


> The constructor list is clearly an array of characters.
> It's not even a mixture of types, which is what others were worring
> about.

One clearly mixes different types: They all differ in the length-type
parameter.


> In answer to your specific question:
>
> declare c(5) character (32000) varying initial (
> a, b, 'abcd'||'ab'||a, a||b||'ab'||a, char_returning_function(b) );

And what's the character length the array has? In my example it matters
even more as the left-hand side (LHS) has a deferred length, contrary to
this example. Thus, the LHS is (re)allocated with the length-type
parameter of the expression on the right, i.e. the array constructor.


However, I found a better example:

real(selected_real_kind(radix=2)) :: b
real(selected_real_kind(radix=10)) :: d

call proc([b, d])

where "b" is a binary floating-point number (radix=2) and "d" is a
decimal floating-point number (radix=10). And to make it complete,
"proc" is a generic name for two specific subroutines, one taking a
binary and one taking a decimal floating point number as argument.
However, the same issue occurred for the program as is - with an
implicit interface of "proc".

I do not see how this can be solved without a type spec. And, thus, I
don't think that PL/I has solved this 45+ years ago.

(I am not saying that PL/I didn't do a sensible choice. However, for the
Fortran language, it is sensible to require a type-spec - as the Fortran
standard does.)

Tobias

Robin Vowels

unread,
Feb 28, 2012, 9:20:42 AM2/28/12
to
On Feb 28, 8:33 pm, glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
In this ng, I posted an example of constructors using PL/I's
preprocessor. Constructors are not a language feature of PL/I.
The closest thing to a constructor in P/I is:

declare c(*) character (32000) controlled;
allocate c(5) initial (1, 5.5e0, 3.4, 7, 99.999);

which, effectively, is all an assignment of a constructor really is.

For a character example similar to the earlier Fortran one:

allocate c(5) initial ((a), (b), 'abc', 'defg',
(some_char_function()) );

> one could:
>
> STRUCT = [ 1, 2.0, 3.1, 4 ];
>
> You can, though, assign a constant:
>
>    STRUCT = 3;
>
> or use it in an expression:
>
>    STRUCT = SQRT(STRUCT);

Or STRUCT could be assigned from another structure having
entirely different types from the elements of STRUCT.

Robin Vowels

unread,
Feb 28, 2012, 9:08:49 AM2/28/12
to
On Feb 28, 10:03 pm, Tobias Burnus <bur...@net-b.de> wrote:
> On 02/28/2012 09:57 AM, Robin Vowels wrote:
>
> > On Feb 28, 6:12 pm, Tobias Burnus<bur...@net-b.de>  wrote:
> >> Robin Vowels wrote:
> >>> It's something that was resolved 45+ years when PL/I
> >>> was designed.
> >> Okay, how do you resolve the equivalent to the following in PL/I?
>
> >>     c = [a, b, [ "abcd", a//b ]//"ab" // a, char_returning_function(b)]
>
> >> I am not claiming that it is impossible to solve, but it is surely not
> >> trivial to do so and definitely not possible at compile time.
>
> > Definitely not possible to do what?
> > Generate the code to call the function?
> > The catenations?
>
> The point is: What's the length-type parameter of the array constructor?
> By itself, it is not obvious as there are at the end 5 array elements,
> which (might) have all different lengths.

In the case of Fortran, it's simply resolved by choosing the longest
length of the elements in the constructor list.

In PL/I, the problem doesn't arise, because elements in a
character array are not required to have the same length.
(See the attribute VARYING in the PL/I example that I gave earlier.)

> > The constructor list is clearly an array of characters.
> > It's not even a mixture of types, which is what others were worring
> > about.
>
> One clearly mixes different types: They all differ in the length-type
> parameter.

As I said before, choose the longest length. Then nothing is lost.

> > In answer to your specific question:
>
> > declare c(5)  character (32000) varying initial (
> >     a, b, 'abcd'||'ab'||a, a||b||'ab'||a, char_returning_function(b) );
>
> And what's the character length the array has?

whatever the length is of each individual element.
That's what VARYING does. Only the characters in each
element are stored.

> In my example it matters
> even more as the left-hand side (LHS) has a deferred length, contrary to
> this example. Thus, the LHS is (re)allocated with the length-type
> parameter of the expression on the right, i.e. the array constructor.

As I communicated earlier, it's resolved simply by choosing the length
of the longest string. Then nothing is lost.

> However, I found a better example:
>
>     real(selected_real_kind(radix=2)) :: b
>     real(selected_real_kind(radix=10)) :: d
>
>     call proc([b, d])
>
> where "b" is a binary floating-point number (radix=2) and "d" is a
> decimal floating-point number (radix=10). And to make it complete,
> "proc" is a generic name for two specific subroutines, one taking a
> binary and one taking a decimal floating point number as argument.
> However, the same issue occurred for the program as is - with an
> implicit interface of "proc".
>
> I do not see how this can be solved without a type spec. And, thus, I
> don't think that PL/I has solved this 45+ years ago.

No typespec is required. See my earlier Fortran example.

In PL/I, in an assignment to a character array "c" defined as above,
it doesn't matter whether the RHS consists of integer, float [aka
real],
or character values, any non-character elements are promoted to
character. And it doesn't matter whether the elements are of
different lengths.

> (I am not saying that PL/I didn't do a sensible choice. However, for the
> Fortran language, it is sensible to require a type-spec - as the Fortran
> standard does.)

BTW, a type-spec isn't required in Fortran; it's an option.
(Earlier, I gave an example of mixed types, without using a typespec,
which can be used with compilers earlier than F2003.)

Tobias Burnus

unread,
Feb 28, 2012, 10:27:37 AM2/28/12
to
On 02/28/2012 03:08 PM, Robin Vowels wrote:
> On Feb 28, 10:03 pm, Tobias Burnus<bur...@net-b.de> wrote:
>> However, I found a better example:
>>
>> real(selected_real_kind(radix=2)) :: b
>> real(selected_real_kind(radix=10)) :: d
>>
>> call proc([b, d])
>>
>> where "b" is a binary floating-point number (radix=2) and "d" is a
>> decimal floating-point number (radix=10). And to make it complete,
>> "proc" is a generic name for two specific subroutines, one taking a
>> binary and one taking a decimal floating point number as argument.
>> However, the same issue occurred for the program as is - with an
>> implicit interface of "proc".
>>
>> I do not see how this can be solved without a type spec. And, thus, I
>> don't think that PL/I has solved this 45+ years ago.
>
> No typespec is required. See my earlier Fortran example.

I disagree:

First, will [b, d] be an array of binary or of decimal floating-point
numbers? At least Fortran does not allow one to mix different
types/kinds in a single array. There is also no obvious solution like
promoting [1, 1.0, 2.0d0] to an array with double-precision elements.
And in this example, you cannot even make use of the left-hand side as
there is none.

Secondly, the Fortran standard mandates:

C4103 (R469) If type-spec is omitted, each ac-value expression in the
array-constructor shall have the same declared type and kind type
parameters.

And:

"If type-spec is omitted, each ac-value expression in the array
constructor shall have the same length type parameters; in this case,
the declared type and type parameters of the array constructor are those
of the ac-value expressions."

Thus, I maintain: One needs a type-spec because the standard mandates
one and because the there is no obvious choice to which one
promotes/converts elements in case of mixing binary/decimal values.

In case of mixing integers with reals or single with double precision
reals, but also in case of character strings, I concur that one could
implemented a version where different values are automatically promoted
- be it from integer to real, from single to double precision or to the
longest string.


> BTW, a type-spec isn't required in Fortran; it's an option.

But only if all types are the same (cf. Fortran 2008's C4103).


> (Earlier, I gave an example of mixed types, without using a typespec,
> which can be used with compilers earlier than F2003.)

Well, compilers assume lazy users and allow with default options more
than the standard mandates. One can argue whether that's good or not. In
any case, if your compiler allows it with standard checking enabled, it
is broken.

Additionally, I am sure that for the character example, several (most?
all?) compilers won't create an array using the longest string, but
choose, e.g., the length of the first element or of the last argument,
or of an element where the length is known at compile time or ...

Searching - at run time! - for the element with the longest string
length is a waste of CPU cycles as it is known that the length of all
strings is the same. The user has promised that. Though, the compiler
might check this when using a flags such as -fcheck=bounds, -CB, -C all
or similar.

Tobias

glen herrmannsfeldt

unread,
Feb 28, 2012, 12:58:42 PM2/28/12
to
In comp.lang.fortran Robin Vowels <robin....@gmail.com> wrote:

(snip on array constructor type)

>> Last I knew, PL/I and C allowed for array initializers, but
>> nothing like Fortran array constructors.

(snip)
> In this ng, I posted an example of constructors using PL/I's
> preprocessor. Constructors are not a language feature of PL/I.
> The closest thing to a constructor in P/I is:

> declare c(*) character (32000) controlled;
> allocate c(5) initial (1, 5.5e0, 3.4, 7, 99.999);

Maybe, but it isn't very close.

Well, I consider array constructors like unnamed array constants.
You can use PARAMETER for a named array constant, which has
a declared type.

> which, effectively, is all an assignment of a constructor really is.

In C, one uses an initialized static array, which is pretty similar
to an initialized Fortran array, either in a DATA statement, or
initialized on its declaration. Java has static final, which means
that you can't modify it, so it really is a constant.

C string constants are pretty much constant arrays of char.
In K&R C, string constants were modifyable, but in ANSI C you
aren't supposed to do that. Some compilers allow it as an
extension.

I tried:

use iso_c_binding
print *,c_loc( [ 1, 2, 3 ] )
end

in gfortran 4.4.5 to see if array constructors had an address,
but it got an internal compiler error.

-- glen

glen herrmannsfeldt

unread,
Feb 28, 2012, 1:23:04 PM2/28/12
to
In comp.lang.fortran Tobias Burnus <bur...@net-b.de> wrote:
> On 02/28/2012 09:57 AM, Robin Vowels wrote:

(snip, someone wrote)
>>> Okay, how do you resolve the equivalent to the following in PL/I?

>>> c = [a, b, [ "abcd", a//b ]//"ab" // a, char_returning_function(b)]

>>> I am not claiming that it is impossible to solve, but it is surely
>>> not trivial to do so and definitely not possible at compile time.

PL/I doesn't do it, but it would have been trivial. PL/I allows
for structure expressions, so it would be a structure containing
different types. They would be converted on assignment.

(snip)
> The point is: What's the length-type parameter of the array constructor?
> By itself, it is not obvious as there are at the end 5 array
> elements, which (might) have all different lengths.

(snip)
> One clearly mixes different types: They all differ in the length-type
> parameter.

>> In answer to your specific question:
>>
>> declare c(5) character (32000) varying initial (
>> a, b, 'abcd'||'ab'||a, a||b||'ab'||a, char_returning_function(b) );

> And what's the character length the array has?

The length is 32000. PL/I has varying length strings which, in
the implementations I know are allocated at the maximum length,
and use a current length field.

> In my example it matters even more as the left-hand side
> (LHS) has a deferred length, contrary to this example.
> Thus, the LHS is (re)allocated with the length-type parameter
> of the expression on the right, i.e. the array constructor.

> However, I found a better example:

> real(selected_real_kind(radix=2)) :: b
> real(selected_real_kind(radix=10)) :: d

The traditional implementation of PL/I's FLOAT DECIMAL is more
like the Fortran REAL(SELECTED_REAL_KIND(n)), in that it allows
one to specify the precision in decimal digits. On machines
supporting both binary and decimal floating point, it would
presumably be used to select between them. (I don't know if
IBM has done that with their PL/I compilers on z/ machines.)

FIXED DECIMAL in PL/I is usually implemented by IBM using
the packed decimal (BCD) data type available in S/360 and
descendants, but some compilers implement it in binary.
Binary implementations will multiply and divide by the
appropriate power of 10 when scale changes are needed,
where BCD implementations only need a shift.

> call proc([b, d])

> where "b" is a binary floating-point number (radix=2) and "d" is a
> decimal floating-point number (radix=10). And to make it complete,
> "proc" is a generic name for two specific subroutines, one taking a
> binary and one taking a decimal floating point number as argument.
> However, the same issue occurred for the program as is - with an
> implicit interface of "proc".

> I do not see how this can be solved without a type spec. And, thus, I
> don't think that PL/I has solved this 45+ years ago.

PL/I's ability to do type conversion gets around some of the
problems. Among others, the PL/I ENTRY statement allows for type
conversion to the appropriate type. PL/I will also convert arguments
on procedure calls when needed, but only one way. (A modifyable
temporary is created, assigned the converted value, and passed
to the callee.)

> (I am not saying that PL/I didn't do a sensible choice.
> However, for the Fortran language, it is sensible to require
> a type-spec - as the Fortran standard does.)

-- glen

Richard Maine

unread,
Feb 28, 2012, 1:30:11 PM2/28/12
to
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

> Well, I consider array constructors like unnamed array constants.

Except that they aren't (necessarily) constant. Indeed, most of the
really nasty cases are distinctly non-constant. You can have references
to user-written functions and to variables with values that were input
from a file. If you restrict yourself to the constant cases, then you'll
pretty much completely miss the whole point of the problems that lead to
the restrictions (like one other poster here who tends to illustrate how
he has no idea what the issues are, while loudly proclaiming how trivial
a solution would be).

And no, I'm not going to debate with him, or even directly reply to his
posts. Been there. Done that. If he thinks he has an actual solution, he
is free to make a formal and concrete proposal to the committee, where
it can get seriously discussed without playing the game of "change the
subject whenever I don't have a good answer." I'm sure the committee
would be very receptive to an actual solution. They sure spent a lot of
time trying to do one. "Solutions" like "it is so easy for me that I
don't need to bother to write down the details" aren't likely to go very
far. Nor are "solutions" like "just change everything else in the
language and it would all work".

(PL/I newsgroup omitted because bringing up PL/I at all was related to
his missing the point).

glen herrmannsfeldt

unread,
Feb 28, 2012, 1:47:52 PM2/28/12
to
In comp.lang.fortran Tobias Burnus <bur...@net-b.de> wrote:
> On 02/28/2012 03:08 PM, Robin Vowels wrote:
>> On Feb 28, 10:03 pm, Tobias Burnus<bur...@net-b.de> wrote:
>>> However, I found a better example:
>
>>> real(selected_real_kind(radix=2)) :: b
>>> real(selected_real_kind(radix=10)) :: d

>>> where "b" is a binary floating-point number (radix=2) and "d" is a
>>> decimal floating-point number (radix=10).

(snip)

> I disagree:

> First, will [b, d] be an array of binary or of decimal floating-point
> numbers? At least Fortran does not allow one to mix different
> types/kinds in a single array. There is also no obvious solution like
> promoting [1, 1.0, 2.0d0] to an array with double-precision elements.
> And in this example, you cannot even make use of the left-hand side as
> there is none.

Note that there is a fundamental difference between PL/I types
with attributes, and Fortran's SELECTED_xxx_KIND.

Someone recently wanted the compiler to distinguish between
different SELECTED_xxx_KINDs that were the same KIND.

For most Fortran compilers, SELECTED_REAL_KIND(10) and
SELECTED_REAL_KIND(11) are the same KIND. In PL/I,
FLOAT DECIMAL(10) and FLOAT DECIMAL(11) are different
types, even though they likely have the same internal
representation. (Well, different PRECISION, same other
attributes.)

Even more, constants have the attributes as they are
written. 10.2 is FIXED DEC(3,2). 10.2e0 is FLOAT DEC(3).
One expects the compiler to do conversions at compile time
where possible, though, as with Fortran, many could be
done at run time.

> Secondly, the Fortran standard mandates:

> C4103 (R469) If type-spec is omitted, each ac-value expression in the
> array-constructor shall have the same declared type and kind type
> parameters.

Assuming PL/I had array contructors, that would have been
very inconvenient.

> And:

> "If type-spec is omitted, each ac-value expression in the array
> constructor shall have the same length type parameters; in this case,
> the declared type and type parameters of the array constructor are those
> of the ac-value expressions."

> Thus, I maintain: One needs a type-spec because the standard mandates
> one and because the there is no obvious choice to which one
> promotes/converts elements in case of mixing binary/decimal values.

Is it required that SELECTED_REAL_KIND(RADIX=2) and
SELECTED_REAL_KIND(RADIX=10) be different KINDs?

> In case of mixing integers with reals or single with double precision
> reals, but also in case of character strings, I concur that one could
> implemented a version where different values are automatically promoted
> - be it from integer to real, from single to double precision or to the
> longest string.

-- glen

stan

unread,
Feb 28, 2012, 1:45:30 PM2/28/12
to
Robin Vowels wrote:
> On Feb 28, 10:03 pm, Tobias Burnus <bur...@net-b.de> wrote:
>> On 02/28/2012 09:57 AM, Robin Vowels wrote:
>>
>> > On Feb 28, 6:12 pm, Tobias Burnus<bur...@net-b.de>  wrote:
>> >> Robin Vowels wrote:
>> >>> It's something that was resolved 45+ years when PL/I
>> >>> was designed.
>> >> Okay, how do you resolve the equivalent to the following in PL/I?
>>
>> >>     c = [a, b, [ "abcd", a//b ]//"ab" // a, char_returning_function(b)]
>>
>> >> I am not claiming that it is impossible to solve, but it is surely not
>> >> trivial to do so and definitely not possible at compile time.
>>
>> > Definitely not possible to do what?
>> > Generate the code to call the function?
>> > The catenations?
>>
>> The point is: What's the length-type parameter of the array constructor?
>> By itself, it is not obvious as there are at the end 5 array elements,
>> which (might) have all different lengths.
>
> In the case of Fortran, it's simply resolved by choosing the longest
> length of the elements in the constructor list.
>
> In PL/I, the problem doesn't arise, because elements in a
> character array are not required to have the same length.
> (See the attribute VARYING in the PL/I example that I gave earlier.)

Seems like PL/I "solved" a different problem in a different context in
a different way.

Tobias Burnus

unread,
Feb 28, 2012, 3:07:24 PM2/28/12
to
Am 28.02.2012 19:47, schrieb glen herrmannsfeldt:
> Is it required that SELECTED_REAL_KIND(RADIX=2) and
> SELECTED_REAL_KIND(RADIX=10) be different KINDs?

I think yes. Maybe not formally, but it is kind of difficult to map a
decimal and a binary FP number to the same internal representation.
However, the standard does not require that radix=10 has to be
supported. (I think, radix=2 is expected to exist - at least by users -,
but it is probably not required either.)

I do not know whether there is any Fortran compiler, which supports
decimal FP numbers - nor whether there is true demand for it.

(My impression is that DFP doesn't really solve the precision/rounding
issue and just leads to a false sense of security; if one has a
sufficient number of significant digits, the radix should not matter and
if the precision is barely enough, one is asking for trouble independent
of the radix. There are probably some few cases where DFP are truly
useful. [I might also misremember or misinterpret what I have read quite
a while ago.])

Has anyone missed DFP? (Or BCD for that matter.)

Tobias

Gordon Sande

unread,
Feb 28, 2012, 4:04:57 PM2/28/12
to
If you do financial calculations (real money and not just talking about
money) then
you will find that the results are specified in decimal. Interest rates
may come
given to four decimal places and the results are expected to be
unambigous to the
smallest currency unit. I was once a rather close observer of some
serious financial
calculations and I was amazed to find that there were an immense number
of fully
specified and distinct ways to calcluate the interest on bonds. The issues were
things like when did the compounding interest itself get treated as part of the
principal. Many of the conventions were intended to make things simpler in the
days of manual bookkeeping. Had the opposite effect when an automated
system was
trying to follow several different schemes!

Real arithmetic can be either floating point or fixed point. If you read the
classical numerical analysis texts you will see both discussed. Financial
computations tend to be decimal fixed point.

I seem to recall an early F77 for PC that came with an emulation package for
real arithmetic that had two versions. One was binary and the other decimal.

Harald Anlauf

unread,
Feb 28, 2012, 4:09:20 PM2/28/12
to
On Feb 28, 9:07 pm, Tobias Burnus <bur...@net-b.de> wrote:

> I do not know whether there is any Fortran compiler, which supports
> decimal FP numbers - nor whether there is true demand for it.
>
> (My impression is that DFP doesn't really solve the precision/rounding
> issue and just leads to a false sense of security; if one has a
> sufficient number of significant digits, the radix should not matter and
> if the precision is barely enough, one is asking for trouble independent
> of the radix. There are probably some few cases where DFP are truly
> useful. [I might also misremember or misinterpret what I have read quite
> a while ago.])
>
> Has anyone missed DFP? (Or BCD for that matter.)

I think the COBOL guys will not be lurking here in c.l.f. :-)
Only some jealous PL/I campaigners...

Harald

glen herrmannsfeldt

unread,
Feb 28, 2012, 4:18:28 PM2/28/12
to
Tobias Burnus <bur...@net-b.de> wrote:

(snip, I wrote)
>> Is it required that SELECTED_REAL_KIND(RADIX=2) and
>> SELECTED_REAL_KIND(RADIX=10) be different KINDs?

> I think yes. Maybe not formally, but it is kind of difficult to map a
> decimal and a binary FP number to the same internal representation.

Before the thought about DFP, I had wondered why no SELECTED_xxx_KIND
allowing one to specify bits. For the usual processors, and the
available hardware formats, specifying in decimal digits allows one
to get the right value, but there is often the assumption of eight-bit
bytes. (PL/I began when many different word lengths were popular.)

> However, the standard does not require that radix=10 has to be
> supported. (I think, radix=2 is expected to exist - at least by
> users -, but it is probably not required either.)

Many hardware features were designed around Fortran requirements.
There are stories that Java's requirement for IEEE (binary)
floating point led to its addition to ESA/390.

> I do not know whether there is any Fortran compiler, which supports
> decimal FP numbers - nor whether there is true demand for it.

As far as I know, the z/Architecture Fortran compilers are way
behind in the standard. It might be that COBOL has it, though.

> (My impression is that DFP doesn't really solve the
> precision/rounding issue and just leads to a false sense
> of security; if one has a sufficient number of significant
> digits, the radix should not matter and if the precision is
> barely enough, one is asking for trouble independent of the
> radix. There are probably some few cases where DFP are truly
> useful. [I might also misremember or misinterpret what I have
> read quite a while ago.])

I might have thought that, too. But sometimes I believe that the
reduction in posts by people who have answers rounded unexpectedly
would be enough. Logic is so cheap now, though not necessarily
debugging and testing. Most of us, even though we are pretty
used to binary, still expect answers in decimal. (I presume still
no format descriptor for floating point binary output.)

So, yes, there should be enough precision, but if one wants
decimal digits in the answer, one can still be surprised.

DFP should give results that are easier to compare to
handheld calculator results, which usually use DFP.

> Has anyone missed DFP? (Or BCD for that matter.)

All those peoply who post, wondering why 0.1*10.0 doesn't
(always) equal 1.0.

-- glen

glen herrmannsfeldt

unread,
Feb 28, 2012, 4:39:44 PM2/28/12
to
Gordon Sande <Gordon...@gmail.com> wrote:

(snip, someone wrote)
>> Has anyone missed DFP? (Or BCD for that matter.)

> If you do financial calculations (real money and not just
> talking about money) then you will find that the results are
> specified in decimal.

(but not usually float decimal)

> Real arithmetic can be either floating point or fixed point.
> If you read the classical numerical analysis texts you will
> see both discussed. Financial computations tend to be
> decimal fixed point.

> I seem to recall an early F77 for PC that came with an
> emulation package for real arithmetic that had two versions.
> One was binary and the other decimal.

The 8080 supports add and subtract in decimal, with a special
carry flag and decimal adjust instruction. If you do all floating
point arithmetic in software, then it is about as easy either way.

The 8080 instructions were kept with the 8086, along with a few
new ones. Some of the early PC compilers were modified versions
of 8080 compilers.

-- glen

glen herrmannsfeldt

unread,
Feb 28, 2012, 5:15:08 PM2/28/12
to
Richard Maine <nos...@see.signature> wrote:

(snip, I wrote)
>> Well, I consider array constructors like unnamed array constants.

> Except that they aren't (necessarily) constant. Indeed, most of the
> really nasty cases are distinctly non-constant.

What I was thinking was closer to what Java calls immutable.

> You can have references
> to user-written functions and to variables with values that were input
> from a file. If you restrict yourself to the constant cases, then you'll
> pretty much completely miss the whole point of the problems that lead to
> the restrictions (like one other poster here who tends to illustrate how
> he has no idea what the issues are, while loudly proclaiming how trivial
> a solution would be).

So, references but not the actual object?

glen herrmannsfeldt

unread,
Feb 28, 2012, 5:21:32 PM2/28/12
to
Richard Maine <nos...@see.signature> wrote:

(snip, I wrote)
>> Well, I consider array constructors like unnamed array constants.

(sorry about accidentally posting before it was finished.)

> Except that they aren't (necessarily) constant. Indeed, most of the
> really nasty cases are distinctly non-constant.

Maybe more like Java's immutable. Once created they can't change.

> You can have references
> to user-written functions and to variables with values that were input
> from a file. If you restrict yourself to the constant cases, then you'll
> pretty much completely miss the whole point of the problems that lead to
> the restrictions (like one other poster here who tends to illustrate how
> he has no idea what the issues are, while loudly proclaiming how trivial
> a solution would be).

OK, but reference but not actual objects. (Sorry, Java terminology.)

I tried:

integer, pointer:: x(:)
x => [ 1, 2, 3 ]
print *,x

which failed for obvious reasons, but I did want to see anyway.
If you can point a pointer to it, you can change try to change it.

I didn't even try putting one on the left side of an assignment.

My c_loc() test failed due to ICE.

-- glen

Robin Vowels

unread,
Feb 28, 2012, 6:42:13 PM2/28/12
to
On Feb 29, 2:27 am, Tobias Burnus <bur...@net-b.de> wrote:
> On 02/28/2012 03:08 PM, Robin Vowels wrote:
>
> > On Feb 28, 10:03 pm, Tobias Burnus<bur...@net-b.de>  wrote:
> >> However, I found a better example:
>
> >>      real(selected_real_kind(radix=2)) :: b
> >>      real(selected_real_kind(radix=10)) :: d
>
> >>      call proc([b, d])
>
> >> where "b" is a binary floating-point number (radix=2) and "d" is a
> >> decimal floating-point number (radix=10). And to make it complete,
> >> "proc" is a generic name for two specific subroutines, one taking a
> >> binary and one taking a decimal floating point number as argument.
> >> However, the same issue occurred for the program as is - with an
> >> implicit interface of "proc".
>
> >> I do not see how this can be solved without a type spec. And, thus, I
> >> don't think that PL/I has solved this 45+ years ago.
>
> > No typespec is required.  See my earlier Fortran example.
>
> I disagree:

Did you forget my previous example?

"Alternatively, it can be written as

"v = (/ v, real( (/ 1, 2, 3, 4, 5 /) ) /)"

which, as I pointed out previously, can be used with pre-F2003
compilers (and subsequent compilers, of course).

> First, will [b, d] be an array of binary or of decimal floating-point
> numbers? At least Fortran does not allow one to mix different
> types/kinds in a single array.

We know this. My example shows how it would be written.

> There is also no obvious solution like
> promoting [1, 1.0, 2.0d0] to an array with double-precision elements.

Use the REAL function, as in my earlier example, with kind.

> And in this example, you cannot even make use of the left-hand side as
> there is none.

No need to, as that's irrelevant anyway.
The LHS (if any) cannot influence what is inside an array constructor
on the RHS -- or any kind of RHS, for that matter.

> Secondly, the Fortran standard mandates:
>
> C4103 (R469) If type-spec is omitted, each ac-value expression in the
> array-constructor shall have the same declared type and kind type
> parameters.

So? And my example doesn't?

> And:
>
> "If type-spec is omitted, each ac-value expression in the array
> constructor shall have the same length type parameters; in this case,
> the declared type and type parameters of the array constructor are those
> of the ac-value expressions."

That's not relevant. It's a requirement in Fortran, but not in PL/I,
fortunately.

> Thus, I maintain: One needs a type-spec because the standard mandates
> one and because the there is no obvious choice to which one
> promotes/converts elements in case of mixing binary/decimal values.

See my example.

> In case of mixing integers with reals or single with double precision
> reals, but also in case of character strings, I concur that one could
> implemented a version where different values are automatically promoted
> - be it from integer to real, from single to double precision or to the
> longest string.

Indeed it could have been, and should have been.

> > BTW, a type-spec isn't required in Fortran; it's an option.
>
> But only if all types are the same (cf. Fortran 2008's C4103).

See my example.

> > (Earlier, I gave an example of mixed types, without using a typespec,
> > which can be used with compilers earlier than F2003.)
>
> Well, compilers assume lazy users and allow with default options more
> than the standard mandates. One can argue whether that's good or not. In
> any case, if your compiler allows it with standard checking enabled, it
> is broken.

It's not broken. Did you try my example?

>
> Additionally, I am sure that for the character example, several (most?
> all?) compilers won't create an array using the longest string, but
> choose, e.g., the length of the first element or of the last argument,
> or of an element where the length is known at compile time or ...

They won't -- nut under the current rules.
I pointed out that it _could_ have been implemented by
choosing the length of the longest string.

> Searching - at run time! - for the element with the longest string
> length is a waste of CPU cycles as it is known that the length of all
> strings is the same. The user has promised that.

Only because those who designed the standard insisted that all the
lengths be the same. That, however, is a pain in the neck,
as typically the lengths are going to be different. (consider a table
of English words.)

Robin Vowels

unread,
Feb 28, 2012, 6:51:20 PM2/28/12
to
On Feb 29, 4:58 am, glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
> In comp.lang.fortran Robin Vowels <robin.vow...@gmail.com> wrote:
>
> (snip on array constructor type)
>
> >> Last I knew, PL/I and C allowed for array initializers, but
> >> nothing like Fortran array constructors.
>
> (snip)
>
> > In this ng, I posted an example of constructors using PL/I's
> > preprocessor.  Constructors are not a language feature of PL/I.
> > The closest thing to a constructor in PL/I is:
> > declare c(*) character (32000) controlled;
> > allocate c(5) initial (1, 5.5e0, 3.4, 7, 99.999);
>
> Maybe, but it isn't very close.

But c = [1, 5.5e0, 3.4, 7, 99.999];

is.
And, of course, it's not far from
allocate c(5) initial (1, 5.5e0, 3.4, 7, 99.999);

> Well, I consider array constructors like unnamed array constants.

Only if they contain constants.

> You can use PARAMETER for a named array constant, which has
> a declared type.

But only for constants.

Richard Maine

unread,
Feb 28, 2012, 6:56:17 PM2/28/12
to
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

> Richard Maine <nos...@see.signature> wrote:
>
> (snip, I wrote)
> >> Well, I consider array constructors like unnamed array constants.

> > Except that they aren't (necessarily) constant. Indeed, most of the
> > really nasty cases are distinctly non-constant.
>
> Maybe more like Java's immutable. Once created they can't change.
>
> > You can have references
> > to user-written functions and to variables with values that were input
> > from a file. If you restrict yourself to the constant cases, then you'll
> > pretty much completely miss the whole point of the problems that lead to
> > the restrictions (like one other poster here who tends to illustrate how
> > he has no idea what the issues are, while loudly proclaiming how trivial
> > a solution would be).
>
> OK, but reference but not actual objects. (Sorry, Java terminology.)
>
> I tried:
>
> integer, pointer:: x(:)
> x => [ 1, 2, 3 ]
> print *,x

That has nothing to do with the question that at least used to be at
hand. I'm talking about complications *WITHIN* the constructor. That
constructor there is about as simple as they come. How the constructor
might itself be used is completely unrelated. Trying to show a use of
the constructor just obfuscates the issue of the constructor itself.
Recall that this is Fortran and that a constructor is defined in a way
independent of its context. Just like 3.1415936535897932384 is a single
precision literal regardless of its context and you will just confuse
matters by putting it in a context where one might expect a double
precision value. The constructor you showed there is just [1, 2, 3].

No, I am not talking about references to the constructor or anything of
the sort. The term "reference" does not even apply to constructors - at
least not in Fortran, which is where we were and is certainly what *I*
was talking about when I used the term. Sorry, but I don't speak Java. I
can sort of vaguely guess what some things might mean, but I'm quite
likely to get the fine points wrong, so I don't even try.

Adequate examples of "nasty" constructors have been posted elsethread.
Dick illustrated one of the nastiest consequences, where you couldn't
even tell at compile time whether the constructor was an integer, real,
or character. Try and use that as, say, an actual argument to a
user-written generic procedure, which might do completely different
things for different argument types. ("Nice" code would do things that
at least had some similarity, but the standard doesn't require such
niceties). And his was really an awfully simple example compared to some
I recall seeing. Then there were the cases that, while doable in theory,
made pretty much every implementor in the room say that their customers
would throw fits at the consequences of forcing the compiler to make
them work. Picture storing an arbitrarily long list of arbitrarily long
strings, each potentially of different length, in something like a
temporary linked list because you need to search (at run time) the whole
list before you can figure out what size to allocate for the result and
you can't just generate it twice because of impure user functions that
get referenced in the process.

I'm really not interested in pursuing it anyway.

Robin Vowels

unread,
Feb 28, 2012, 7:03:50 PM2/28/12
to
On Feb 29, 5:47 am, glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
> In comp.lang.fortran Tobias Burnus <bur...@net-b.de> wrote:
...
> > Secondly, the Fortran standard mandates:
> > C4103 (R469) If type-spec is omitted, each ac-value expression in the
> > array-constructor shall have the same declared type and kind type
> > parameters.
>
> Assuming PL/I had array contructors, that would have been
> very inconvenient.

PL/I has array constructors. In PL/I it's called an INITIAL list.
They cannot, however, be used as universally as array constructors
in Fortran.

Robin Vowels

unread,
Feb 28, 2012, 6:59:38 PM2/28/12
to
On Feb 29, 5:23 am, glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
> In comp.lang.fortran Tobias Burnus <bur...@net-b.de> wrote:
>
> > On 02/28/2012 09:57 AM, Robin Vowels wrote:
>
> (snip, someone wrote)
>
> >>> Okay, how do you resolve the equivalent to the following in PL/I?
> >>>     c = [a, b, [ "abcd", a//b ]//"ab" // a, char_returning_function(b)]
> >>> I am not claiming that it is impossible to solve, but it is surely
> >>> not trivial to do so and definitely not possible at compile time.
>
> PL/I doesn't do it,

PL/I does do it, as I illustrated in the INITIAL list.

> but it would have been trivial. PL/I allows
> for structure expressions, so it would be a structure containing
> different types. They would be converted on assignment.
>
> (snip)
>
> > The point is: What's the length-type parameter of the array constructor?
> > By itself, it is not obvious as there are at the end 5 array
> > elements, which (might) have all different lengths.
>
> (snip)
>
> > One clearly mixes different types: They all differ in the length-type
> > parameter.
> >> In answer to your specific question:
>
> >> declare c(5)  character (32000) varying initial (
> >>     a, b, 'abcd'||'ab'||a, a||b||'ab'||a, char_returning_function(b) );
> > And what's the character length the array has?
>
> The length is 32000.

That's an (arbitrary) maximum length.
The actual length is whatever length each individual element is.

> PL/I has varying length strings which, in
> the implementations I know are allocated at the maximum length,
> and use a current length field.

At least one PL/I subset allocated the actual length.

Dick Hendrickson

unread,
Feb 28, 2012, 9:03:34 PM2/28/12
to
There are two problems with this.

One is practical, given
[ ( repeat( 'x', int_func(i) ) , i = 1,N) ]
how do you find, in a reasonably efficient manner, the longest length?
There seem to be only two solutions. One is to evaluate int_func(i) N
different times, save the results, and (trivially) compute the maximum.
Then use the saved list of int_func(i) to do the repeat function and
append enough blanks. Clearly, the Fortran side-effects rules don't
allow you to evaluate int_func(i) from 1 to N twice. The other is to
just march through the list and go back and add blanks each time a
larger length is encountered. Since N can be large, neither was
believed to be practical.

The other is logical expectations. Given
[ ('xxx', i=1,N), ('a', i = 1,M)]
what should the character length be? 3 or 1? Does it depend on N and
M? Why, or why not? More difficult, given
[ (char_variable(1:f(i)), i = 1,N), (char_variable(1:g(I),I=1,M)]
what should the length be? If N = 0, you can't evaluate f(i) to see
what the value might be. Ditto for M = 0. And if both are zero?

There is simply no obviously right answer for the zero
length/size/iteration-count cases.

Dick Hendrickson

FX

unread,
Feb 29, 2012, 4:08:46 AM2/29/12
to
> use iso_c_binding
> print *,c_loc( [ 1, 2, 3 ] )
> end
>
> in gfortran 4.4.5 to see if array constructors had an address,
> but it got an internal compiler error.

Tobias beat me to reporting it:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52426

--
FX

Thomas Koenig

unread,
Mar 1, 2012, 1:29:02 AM3/1/12
to
Tobias Burnus <bur...@net-b.de> schrieb:

> Has anyone missed DFP? (Or BCD for that matter.)

Of course I miss BCD :-) I used that to calculate the decimal
representation of the then largest-known Mersenne prime on my
Commodore 64 in assembler code (its 6502 had a BCD add instruction).

e p chandler

unread,
Mar 1, 2012, 6:59:50 AM3/1/12
to


"Thomas Koenig" wrote in message
news:jin4vd$4ag$1...@newsreader4.netcologne.de...
---> Actually that microprocessor has a separate mode which causes addition
and subtraction to operate in BCD, unlike the 8080 which has decimal adjust
instructions. Converting "binary" to "decimal" was one of the nice
applications of this feature. Steve Wozniak published a short piece of code
in an early issue of "Apple Orchard" which did it this way:

clear bcd locations
set bcd mode
do n times
shift binary locs left into carry
add bcd locs to self
end do
clear bcd mode
split 4 bit fields and print

-- e


Robin Vowels

unread,
Mar 2, 2012, 2:19:35 AM3/2/12
to
Think of it as an assignmenet to a character array.
It's no more difficult.

Dick Hendrickson

unread,
Mar 3, 2012, 7:59:58 AM3/3/12
to
No, you're missing my point. In a character array assignment the
element size is known and each individual value can be converted to the
right length one at a time. There are no surprises; no need to go back
and fix something or to look ahead to see what the "real" length is.

Dick Hendrickson

Robin Vowels

unread,
Mar 6, 2012, 2:10:17 AM3/6/12
to
I didn't miss the point.
It isn't necessary to "look ahead" to see what the "real" length is.
Nor is it necessary to go back and add blanks as soon each larger
length is encountered, as you suggested.
The running maximum length can be computed as each string /
string expression is encountered, so that by the time the last string
has been processed, the maximum length is known.
Using the actual lengths stored with each resultant string,
assignments
can then be made to the LHS of an assignment or to an un-named
variable.
At this time, blanks would be appended (if necessary) for strings
shorter than the maximum, which would in any case happen when
an array is assigned to another where the length is longer.

I might point out that in PL/I, strings can be fixed length
(as in Fortran) and varying length. Further, individual elements
of an array of varying strings can have different lengths.
The lengths of individual elements of an initial list can all be
different, even if the string array is of fixed length.
0 new messages