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

Re: gfortran rhs reallocation

58 views
Skip to first unread message

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

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

John W Kennedy

unread,
Feb 28, 2012, 5:53:28 PM2/28/12
to
On 2012-02-28 18:23:04 +0000, glen herrmannsfeldt said:
> 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.)

It's a compile-time option, FLOAT(DFP) makes all FLOAT DECIMAL the real
thing; FLOAT(NODFP) makes FLOAT DECIMAL either 360 hexadecimal or IEEE
binary, depending on the same things that control which FLOAT BINARY is.

--
John W Kennedy
"The blind rulers of Logres
Nourished the land on a fallacy of rational virtue."
-- Charles Williams. "Taliessin through Logres: Prelude"

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.

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

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