Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
공지
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
29286 토론

Ifort accepts invalid elemental character function and terminates at run time

Vivek_R_
초보자
2,053 조회수

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 포인트
10 응답
Steve_Lionel
명예로운 기여자 III
2,034 조회수

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 포인트
JohnNichols
소중한 기여자 III
2,008 조회수
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 포인트
FortranFan
명예로운 기여자 III
1,918 조회수

 

@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 포인트
Vivek_R_
초보자
2,001 조회수

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 포인트
JNichols
새로운 기여자 I
1,990 조회수

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 포인트
Ron_Green
중재자
1,975 조회수

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 포인트
JohnNichols
소중한 기여자 III
1,957 조회수
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 포인트
Steve_Lionel
명예로운 기여자 III
1,947 조회수

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 포인트
JohnNichols
소중한 기여자 III
1,938 조회수

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 포인트
Steve_Lionel
명예로운 기여자 III
1,905 조회수

Good catch - yes, that should be an error. 

0 포인트
응답