Elemental character function

I think the mytrim function below is illegal since len_trim(x) may give distinct integers for array x(:) and a character array must have elements of equal LEN, but the program compiles with both

gfortran -std=f2018 mytrim.f90
ifort -stand:f18 mytrim.f90

However, g95 says

In file mytrim.f90:5

character (len=len_trim(x))   :: y
                        1
Error: Dummy variable 'x' at (1) of an ELEMENTAL procedure cannot appear in a specification expression

flang (clang version 7.0.1) gives an error message that does not explain what is wrong with the code:

/tmp/mytrim-8a3702.ll:146:21: error: use of undefined value '%x'
        %30 = bitcast i64* %x to i8*, !dbg !32
module m
contains
elemental function mytrim(x) result(y)
character (len=*), intent(in) :: x
character (len=len_trim(x))   :: y
y = trim(x)
end function mytrim
end module m
!
program test_mytrim
use m
print "(a,'_')", mytrim(["Fortran","Julia  "])
end program test_mytrim

At run-time Intel crashes and gfortran gives output

Fortran_
Julia_
2 Likes

Indeed, otherwise that will be a workaround to generate “jagged arrays” in Fortran that the language disallows!

From what I recall, the constraints in the standard with ELEMENTAL procedures are such that with function subprograms, the function RESULT can have a reference to certain specification inquiries but just not all pure or elemental functions:

  • LEN_TRIM is itself ELEMENTAL but that does not fit the bill here.
  • On the other had, my hunch is the use of LEN intrinsic function will be accepted on account of it being an intrinsic inquiry function that is allowed in a specification expression.

Note that gfortran rejects trim on an array. Since len_trim(x) is equivalent to len(trim(x)), rejecting len_trim would make sense.

program a                                                                                           
                                                                                                    
  print*, trim(['a ','ab'])                                                                           
                                                                                                  
end program a

gives
Error: ‘string’ argument of ‘trim’ intrinsic at (1) must be a scalar

Naively one may visualize as such to gain an understanding, but per the semantics of the standard the two are not equivalent: TRIM is specified as a transformational intrinsic function whereas LEN_TRIM is elemental.

@FortranFan: Thanks.
Maybe len_trim is exactly meant to solve the issue that one cannot get the length of trimmed strings in an array without a loop. len_trim() for single strings is nice to have, but the advantage over len(trim()) is not really huge.

MFE (2018) says (sect. 7.9 Elemental procedures, p. 127/128):

[…] function result must be a scalar variable that is not allocatable, is not a pointer, and does not have a type parameter defined by expression other than a constant expression.

I guess it is rule C15103 of the F2018 Draft (N2146, sect. 15.8.1) translated for commoners.

The y result variable obviously has type parameter (length) given by non-constant expression.
edited: C15103, not C15102

The elemental function ‘mytrim’ shown in the original post violates constraint C15103 in the current standard (Fortran 2018, 18-007r1 document) - see highlighted section in the snip below.

The semantics of the specification inquiry mentioned in section 10.1.11 of the standard effectively do not permit the reference to ‘LEN_TRIM’ intrinsic in the function result declaration.