- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am trying to compile the following code with Intel Fortran 11.1, where I would like to have the constructor function to be called by a function with the same name of my class.
************************************** shape.f90 **************************************
module shape_mod
private ! hide the type-bound procedure implementation procedures
public :: shape ! allow access to shape & constructor procedure
type shape
private ! hide the underlying details
integer :: color
logical :: filled
integer :: x
integer :: y
contains
private ! hide the type bound procedures by default
procedure :: initShape ! private type-bound procedure
procedure, public :: isFilled ! allow access to isFilled type-bound procedure
procedure, public :: print ! allow access to print type-bound procedure
end type shape
interface shape
procedure constructor
end interface
contains
function constructor(color, filled, x, y)
type(shape) :: constructor
integer :: color
logical :: filled
integer :: x
integer :: y
call constructor%initShape(color, filled, x, y)
end function
logical function isFilled(this)
class(shape) :: this
isFilled = this%filled
end function
subroutine initShape(this, color, filled, x, y)
! initialize shape objects
class(shape) :: this
integer :: color
logical :: filled
integer :: x
integer :: y
this%color = color
this%filled = filled
this%x = x
this%y = y
end subroutine
subroutine print(this)
class(shape) :: this
print *, this%color, this%filled, this%x, this%y
end subroutine
end module
program shape_prg
use shape_mod
type(shape) :: sh
logical filled
sh = shape(5, .true., 100, 200) ! invoke constructor through shape generic interface
call sh%print()
end
************************************** shape.f90 **************************************
But I am getting the following error:
*************************************************************************************
d:\\lc\\shape\\src> ifort shape.f90
Intel Visual Fortran Intel 64 Compiler Professional for applications running on Intel 64, Version 11.1 Build 20100414 Package ID: w_cprof_p_11.1.065
Copyright (C) 1985-2010 Intel Corporation. All rights reserved.
shape.f90(19): error #6643: This statement is incorrectly positioned.
procedure constructor
----------------^
shape.f90(19): error #8168: Parentheses are required after the PROCEDURE keyword.
procedure constructor
----------------^
shape.f90(62): error #6296: The type of this structure constructor is use associated with the PRIVATE fields attribute
[SHAPE]
sh = shape(5, .true., 100, 200) ! invoke constructor through shape generic interface
-------------^
compilation aborted for shape.f90 (code 1)
*************************************************************************************
What am I doing wrong?
Thanks in advance,
Luiz
************************************** shape.f90 **************************************
module shape_mod
private ! hide the type-bound procedure implementation procedures
public :: shape ! allow access to shape & constructor procedure
type shape
private ! hide the underlying details
integer :: color
logical :: filled
integer :: x
integer :: y
contains
private ! hide the type bound procedures by default
procedure :: initShape ! private type-bound procedure
procedure, public :: isFilled ! allow access to isFilled type-bound procedure
procedure, public :: print ! allow access to print type-bound procedure
end type shape
interface shape
procedure constructor
end interface
contains
function constructor(color, filled, x, y)
type(shape) :: constructor
integer :: color
logical :: filled
integer :: x
integer :: y
call constructor%initShape(color, filled, x, y)
end function
logical function isFilled(this)
class(shape) :: this
isFilled = this%filled
end function
subroutine initShape(this, color, filled, x, y)
! initialize shape objects
class(shape) :: this
integer :: color
logical :: filled
integer :: x
integer :: y
this%color = color
this%filled = filled
this%x = x
this%y = y
end subroutine
subroutine print(this)
class(shape) :: this
print *, this%color, this%filled, this%x, this%y
end subroutine
end module
program shape_prg
use shape_mod
type(shape) :: sh
logical filled
sh = shape(5, .true., 100, 200) ! invoke constructor through shape generic interface
call sh%print()
end
************************************** shape.f90 **************************************
But I am getting the following error:
*************************************************************************************
d:\\lc\\shape\\src> ifort shape.f90
Intel Visual Fortran Intel 64 Compiler Professional for applications running on Intel 64, Version 11.1 Build 20100414 Package ID: w_cprof_p_11.1.065
Copyright (C) 1985-2010 Intel Corporation. All rights reserved.
shape.f90(19): error #6643: This statement is incorrectly positioned.
procedure constructor
----------------^
shape.f90(19): error #8168: Parentheses are required after the PROCEDURE keyword.
procedure constructor
----------------^
shape.f90(62): error #6296: The type of this structure constructor is use associated with the PRIVATE fields attribute
[SHAPE]
sh = shape(5, .true., 100, 200) ! invoke constructor through shape generic interface
-------------^
compilation aborted for shape.f90 (code 1)
*************************************************************************************
What am I doing wrong?
Thanks in advance,
Luiz
Link Copied
8 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don't think you're doing anything wrong. I know that the 11.1 and 12.0 compiler does not accept "procedure" in a generic interface. The 12.0 compiler actually does worse on this, triggering an internal compiler error. I already have a bug report filed on this - I will verify that yours is the same issue.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I got it to work with 12.0.3 if I renamed the generic interface and derived type to something other than shape (clash with the intrinsic?) and added the module keyword to the procedure-stmt.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It is indeed the intrinsic SHAPE that is conflicting here, though the compiler's response to that is not very nice. I will report that. Issue ID is DPD200169073.
The standard considers intrinsic procedures and type names to be of the same "local identifier class". It says (F2008, 16.3.1):
"Within its scope, a local identifier of one class shall not be the same as another local identifier of the same class, except that a generic name may be the same as the name of a procedure as explained in 12.4.3.4 or the same name as a derived type (4.5.10)."
So it is fine to have the generic have the same name as the type, but not ok to have the type the same name as an intrinsic. Unfortunately, while the language has a way of "affirming" that an identifier is an intrinsic, it doesn't have a good way of specifying that it is NOT an intrinsic for the purpose of defining a type name.
As Ian writes, Intel Fortran currently insists on the "module" keyword, which will prevent you from using procedure pointers in a generic interface. That has already been reported.
The standard considers intrinsic procedures and type names to be of the same "local identifier class". It says (F2008, 16.3.1):
"Within its scope, a local identifier of one class shall not be the same as another local identifier of the same class, except that a generic name may be the same as the name of a procedure as explained in 12.4.3.4 or the same name as a derived type (4.5.10)."
So it is fine to have the generic have the same name as the type, but not ok to have the type the same name as an intrinsic. Unfortunately, while the language has a way of "affirming" that an identifier is an intrinsic, it doesn't have a good way of specifying that it is NOT an intrinsic for the purpose of defining a type name.
As Ian writes, Intel Fortran currently insists on the "module" keyword, which will prevent you from using procedure pointers in a generic interface. That has already been reported.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The compiler is having a bit of a bet both ways then, as 12.0.3 happily accepts:
[fortran]PROGRAM ShapeShifter
IMPLICIT NONE
TYPE :: Shape
INTEGER :: i
END TYPE Shape
TYPE(Shape) :: z
!***
z%i = 1
PRINT "(I0)", z%i
z = Shape(i=3)
PRINT "(I0)", z%i
END PROGRAM ShapeShifter
[/fortran]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
My explanation was, as "Click and Clack" (The NPR Car Talk guys) would say, BOOOOO-GUSSSS! Something else is going on here and we'll figure out what it is. My point about the MODULE keyword still applies.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
A derived type may have the same name as a generic function. If a reference could be interpreted as either a generic function reference or a structure constructor, it is to be treated as a generic function reference. We arenot doing this right and will fix it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This problem has been fixed in our sources. The fix will appear in a future update.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The internal compiler error is fixed in Update 7. You still need the "module" prefix to "procedure" in the interface block - that will be remedied in a future version.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page