Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Character array RHS allocation

OP1
New Contributor II
391 Views

Per Steve's note regarding the default behavior of RHS allocation, shouldn't we expect an identical behavior for the two assignments shown here?

PROGRAM P
CHARACTER(LEN=:),ALLOCATABLE :: S(:),T(:)
ALLOCATE(CHARACTER(LEN=5) :: S(2),T(2))
S = ['a','abc']
WRITE(*,*) LEN(S)
T = 'a'
WRITE(*,*) LEN(T)
END

 

0 Kudos
6 Replies
Steven_L_Intel1
Employee
391 Views

The same behavior? No. But is the behavior you're seeing correct? No. Also, your program is nonconforming.

First, let's look at:

S = ['a','abc']

This is nonconforming in Fortran 2008 because the lengths of the array constructor values are different.

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

As an extension, we allow this and promote all values to the longest length, so we treat it as if you had written:

S = [CHARACTER(3)::'a','abc']

While the shapes are the same, the length parameters differ so S is deallocated. It is then allocated to the shape and length of the RHS, which is two elements of length 3. This is what you get.

Now for:

T = 'abc'

Since the RHS is a scalar, the shapes don't matter, but the lengths are different so T would be deallocated. It then gets allocated to the same shape it had before with the length parameter of the RHS so a shape of 2 and length of 1. This isn't happening. I remember we had some issues with this scenario during beta test, but thought it got worked out. I guess not - I will let the developers know.

I also want to point out that while in the past we've required a switch to get automatic array reallocations, we always did deferred-length character reallocations. But it looks as if we've always had this particular case wrong! Issue ID is DPD200414618.

 

0 Kudos
OP1
New Contributor II
391 Views

Thanks Steve - this is crystal clear now. I should have turned /stand:f15 to detect the non-conformance.

0 Kudos
OP1
New Contributor II
391 Views

A small variation (if not the same) of the bug above would be:

PROGRAM P
CHARACTER(LEN=:),ALLOCATABLE :: A,B(:)
A = '123456'
ALLOCATE(CHARACTER(LEN=2) :: B(10))
B = A
WRITE(*,*) B
END 

Now, here is my question. Assume we have:

CHARACTER(LEN=:),ALLOCATABLE :: STRING,STRING_ARRAY(:)
STRING = '1234'
ALLOCATE(CHARACTER(LEN=10) :: STRING_ARRAY(100))

How does one assign the values of the scalar STRING to the elements of STRING_ARRAY without having the length of the strings in STRING_ARRAY being changed?

0 Kudos
OP1
New Contributor II
391 Views

ok - I think I got it, sorry for the useless question above.

STRING_ARRAY(:) = STRING(:)

This will either truncate STRING (if its length exceeds the length declared for the strings in STRING_ARRAY) or pad it with blanks.

0 Kudos
Steven_L_Intel1
Employee
391 Views

Yep - putting (:) on the LHS disables the automatic reallocation. You didn't need it on the RHS.

And yes, your program in post 4 is the same bug.

0 Kudos
Steven_L_Intel1
Employee
391 Views

This bug has been fixed - I expect the fix to appear in Update 2 to Parallel Studio XE 2017.

0 Kudos
Reply