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

Ifort accepts invalid elemental character function and terminates at run time

Vivek_R_
Novice
877 Views

As discussed here the elemental function below is invalid because len_trim(x) may give distinct integers for array x(:)and a character array must have elements of equal LEN.

 

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

 

Compiling and running, I get

c:\fortran\test>ifort mytrim.f90

Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.5.0 Build 20211109_000000
Copyright (C) 1985-2021 Intel Corporation. All rights reserved.

Microsoft (R) Incremental Linker Version 14.16.27027.1
Copyright (C) Microsoft Corporation. All rights reserved.

-out:mytrim.exe
-subsystem:console
mytrim.obj

c:\fortran\test>mytrim
forrtl: severe (157): Program Exception - access violation

0 Kudos
10 Replies
Steve_Lionel
Honored Contributor III
858 Views

Yes, the program is invalid, but can you point to a numbered constraint or syntax rule that it violates? Many non-standard things are not required to be diagnosed, and the results are undefined.

Each call to mytrim returns a scalar character value. That the lengths vary is on you. Yes, it would be nice if there was a run-time check that complained, but it's not required by the standard.

0 Kudos
JohnNichols
Valued Contributor III
832 Views
module m
contains
elemental function mytrim(x) result(y)
character (len=*), intent(in) :: x
character (len=len_trim(x)) :: z
integer y

z = trim(x)
y = len(z)
end function mytrim


end module m
!
program test_mytrim
use m
integer name(2)
name = mytrim(["Fortran","Julia "])
print "(I4)", mytrim(["Fortran","Julia "])
end program test_mytrim

This does what you seem to want to do, returning the correct information that the array has a 7 letter word and a trimmed 5 letter word.  

 

0 Kudos
FortranFan
Honored Contributor II
742 Views

 

@Steve_Lionel writes:
Yes, the program is invalid, but can you point to a numbered constraint or syntax rule that it violates? ..

 

The elemental function 'mytrim' shown in the original post violates constraint C15103 in the current standard (Fortran 2018, 18-007r1 document), specifically the part where the standard states, "In the specification-expr that specifies a type parameter value of the result of an elemental function, an object designator with a dummy argument of the function as the base object shall appear only as the
subject of a specification inquiry (10.1.11) .."  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.

el.png

 

@Ron_Green , I suggest following up with the Intel Fortran compiler team toward a compiler bug report.

 

0 Kudos
Vivek_R_
Novice
825 Views

Thanks. The code was meant to demonstrate a possible compiler bug. For the code you showed, one could use the elemental len_trim function to get the same result.

0 Kudos
JNichols
New Contributor I
814 Views

I understood what you were trying to do, but I think sometimes you need to use a few more lines to show the intent to a reader.  

Clearly your Y has the correct result, just returning it is a bit of a pain.  

The problem with languages is the limited set of words.  

 

This is why I love LISP you can quickly move beyond the simple syntax, I mean anyone who enjoys working with car and cdr is clearly an interesting person.  

Fortran you live in the language.  

0 Kudos
Ron_Green
Moderator
799 Views

gfortran 11.2 is flagging the error.  and ifort -stand f18 flags a warning.  We can change that to abort compilation with -warn errors.  I am considering asking the ifort team to change warning 8208 to default to error condition rather than warning.  What do you think?

 

$cat elemtrim.f90 

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

$ gfortran elemtrim.f90
elemtrim.f90:12:35:

   12 | print "(a,'_')", mytrim(["Fortran","Julia "])
      |                                   1
Error: Different CHARACTER lengths (7/6) in array constructor at (1)
$ 
$ # default ifort w/o standards checking
$ ifort elemtrim.f90
$ 
$ # ifort with standards check
$ ifort -stand f18 elemtrim.f90
elemtrim.f90(12): warning #8208: If type specification is omitted, each ac-value expression  in the array constructor of type CHARACTER must have the same length type parameters.   ['Julia ']
print "(a,'_')", mytrim(["Fortran","Julia "])
-----------------------------------^
$ 
$ # ifort with standards check AND treat WARNINGS as ERRORS
$ 
$ ifort -stand f18 -warn errors elemtrim.f90
elemtrim.f90(12): error #8208: If type specification is omitted, each ac-value expression  in the array constructor of type CHARACTER must have the same length type parameters.   ['Julia ']
print "(a,'_')", mytrim(["Fortran","Julia "])
-----------------------------------^
compilation aborted for elemtrim.f90 (code 1)

 

0 Kudos
JohnNichols
Valued Contributor III
781 Views
module m
contains
elemental function mytrim(x) result(y)
character (len=*), intent(in) :: x
character (len=len_trim(x)) :: z
integer y

z = trim(x)
y = len(z)
end function mytrim


end module m
!
program test_mytrim
use m
integer name(2)
name = mytrim(["Fortran","Julia "])
print "(A4,I4, I4)","Here", mytrim(["Fortran","Julia "])
end program test_mytrim

Surely this is a logic error in some form. Mytrim is being called twice, once with Fortran and once with Julia. The problem is that you cannot make name into a character array to take the return values.  

0 Kudos
Steve_Lionel
Honored Contributor III
771 Views

There are two different issues here. One is the array constructor where the lengths of the constants are different. Intel Fortran (and DEC Fortran before that) allowed this as an extension, padding shorter values. I do not recommend making this an error. The committee declined to standardize this behavior, instead making you explicitly specify the length, for example, [character(8)::'Fortran,'Julia']. 

Then there is the issue of an elemental function where it can return character values of different lengths. This is not something a compiler can detect reliably without adding onerous run-time checks.

0 Kudos
JohnNichols
Valued Contributor III
762 Views

The two problems with using the code, the first is the character array should have been properly declared as a "two" element array, the mytrim passes  back the lengths of the trimmed strings correctly and you can then use them at your leisure on the two element array.  As it is you cannot get the trimmed two element array back into the main program as it is written.    

 

Of course if you can I would like to see the code.  The print line calls mytrim - effectively twice according to the debugger. 

0 Kudos
Steve_Lionel
Honored Contributor III
729 Views

Good catch - yes, that should be an error. 

0 Kudos
Reply