- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I would like to build a table of procedures. The program (copied below) fails to compile with the following error:
ifx: remark #10440: Note that use of a debug option without any optimization-level option will turnoff most compiler optimizations similar to use of '-O0'
/app/example.f90(39): error #6592: This symbol must be a defined parameter, an enumerator, or an argument of an inquiry function that evaluates to a compile-time constant. [A]
type(pc), parameter :: table(3) = [pc(a),pc(b),pc(c)] ! Doesn't work
--------------------------------------^
Full program:
! dispatch_test.f90 --
! Dispatch table using procedure pointers
module funcs
abstract interface
function retchar()
character(len=1) :: retchar
end function
end interface
contains
function a()
character(len=1) :: a
a = 'a'
end function
function b()
character(len=1) :: b
b = 'b'
end function
function c()
character(len=1) :: c
c = 'c'
end function
end module
module dispatch_table
use funcs
implicit none
private
public :: table
public :: build_table, pc
! Procedure container
type :: pc
procedure(retchar), pointer, nopass :: rc => null()
end type
! Static dispatch table
type(pc), parameter :: table(3) = [pc(a),pc(b),pc(c)] ! Doesn't work
! According to J3/24-007, section 7.5.10, a procedure target
! can be used in the structure constructor.
contains
! Dynamic dispatch table
function build_table() result(table)
type(pc) :: table(3)
table = [pc(a),pc(b),pc(c)] ! This works
end function
end module
program test
use dispatch_table, only: pc, build_table
implicit none
type(pc) :: table(3)
table = build_table() ! Dynamic table
associate(abc => &
table(1)%rc()//table(2)%rc()//table(3)%rc())
if (abc /= 'abc') stop 1
end associate
block
use dispatch_table, only: table ! Static table
associate(abc => &
table(1)%rc()//table(2)%rc()//table(3)%rc())
if (abc /= 'abc') stop 2
end associate
end block
print *, 'PASS'
end program
Both the NAG Fortran compiler and flang accept this program.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Any opinions on this issue?
As I've tried to illustrate, the initialization of the (dynamic) dispatch table with:
table = [pc(a),pc(b),pc(c)]
is legal. The question is whether this statement is also valid as a constant expression in the initialization of a parameter variable.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This is one for the language lawyers
But, I note that compiling with gfortran 13.1.0 gives:
dispatch_test.f90:39:38:
39 | type(pc), parameter :: table(3) = [pc(a),pc(b),pc(c)] ! Doesn't work
| 1
Error: Parameter ‘a’ at (1) has not been declared or is a variable, which does not reduce to a constant expression
dispatch_test.f90:30:15:
30 | public :: table
| 1
Error: Symbol ‘table’ at (1) has no IMPLICIT type
dispatch_test.f90:55:9:
55 | use dispatch_table, only: pc, build_table
| 1
Fatal Error: Cannot open module file ‘dispatch_table.mod’ for reading at (1): No such file or directory
compilation terminated
Also, looking in John Reid's summary of the new features in Fortran 2023 (N2212.pdf), there doesn't appear to have been any relaxation on what you can have in initialisation expressions.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I also asked the GNU contributors and they sent me here to ask for an opinion: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117070
For the record, also the tickets that saw this behavior fixed/introduced in NAG Fortran and LLVM flang were opened by me. For the Nvidia Fortran compiler (formerly PGI) I was recommended to use a dynamic dispatch table as a workaround.
It would be great if language lawyers could reach a verdict. Otherwise it is just one more unportable behavior.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
My take is that this is valid usage, though it does not astonish me that compilers get this wrong. Here's my logic:
R758 allows a proc-target as a component-data-source.
C7109 says "a proc-target shall correspond to a procedure pointer component.", which it does here.
R1041 says that proc-target can be a procedure-name
C1033 includes a module procedure in the list of allowed uses of a proc-target here

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page