Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
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.
29285 Discussions

SELECT TYPE and polymorphic type comps

jahern
Beginner
597 Views
Hello again,

Here is a chunk of code that I believe should be valid and compile, but it fails for ifort 11.1.056 with an error. The code is:
[plain]MODULE bug3
   IMPLICIT NONE

   TYPE, ABSTRACT :: Shape
      INTEGER :: index
   END TYPE Shape
   TYPE, EXTENDS(Shape) :: Triangle
      INTEGER :: points(3)
   END TYPE Triangle
   TYPE Container
      CLASS(Shape), ALLOCATABLE :: obj
   END TYPE Container

CONTAINS

FUNCTION nSides(this)
   IMPLICIT NONE
   CLASS(Container), INTENT(IN) :: this
   INTEGER :: nSides
   IF (ALLOCATED(this%obj)) THEN
      SELECT TYPE (this%obj)
      CLASS IS (Triangle)
         nSides = 3
      CLASS DEFAULT
         STOP
      END SELECT
   ELSE
      STOP
   ENDIF
END FUNCTION nSides

END MODULE bug3[/plain]
The error I receive is:
[plain]bug3.F90(21): error #8253: If selector expression in SELECT TYPE is not a named 
variable, associate-name=> shall appear.
      SELECT TYPE (this%obj)
------^
compilation aborted for bug3.F90 (code 1)[/plain]
It would seem to me that the %obj component of a TYPE(Container) object should be visible to the function as it must always be present (and the ALLOCATED statement was accepted); I assume this would make it a "named variable". In that case, this would be an error on valid code. Of course, I could always be missing something! This error may be related to my earlier posts, as changing the dummy argument CLASS(Container) to TYPE(Container) additionally generates error #8307 (twice).

Thanks,
Jared

0 Kudos
4 Replies
Steven_L_Intel1
Employee
597 Views

I believe that the compiler is correct. The rule in the standard is worded just like the error message. this%obj is not a named variable, it is an "object designator". So, you'd need to add the associate-name here.
0 Kudos
Kevin_D_Intel
Employee
597 Views

I still error #8253 using a development compiler containing a fix for the earlier internal compiler error (here), so I need to ping Development for further advice about this error and error #8307. More when I know it.
0 Kudos
jahern
Beginner
597 Views

I believe that the compiler is correct. The rule in the standard is worded just like the error message. this%obj is not a named variable, it is an "object designator". So, you'd need to add the associate-name here.

Ah, my mistake, I didn't recognize a difference between named variables and object designators! Adding an associate-name does clear this up (minus the #8307 errors with TYPE substituted for CLASS). I didn't realize that this a was required here - must have missed C835, and reading 8.1.9.1 para 2 led me to believe it was optional. On the surface, it seems odd to require associate-name, but I suppose that if it is a TBP or other procedure, you would just want to execute it once during the SELECT TYPE... perhaps.

Thanks!
0 Kudos
Hirchert__Kurt_W
New Contributor II
597 Views
Quoting - jahern

I believe that the compiler is correct. The rule in the standard is worded just like the error message. this%obj is not a named variable, it is an "object designator". So, you'd need to add the associate-name here.

Ah, my mistake, I didn't recognize a difference between named variables and object designators! Adding an associate-name does clear this up (minus the #8307 errors with TYPE substituted for CLASS). I didn't realize that this a was required here - must have missed C835, and reading 8.1.9.1 para 2 led me to believe it was optional. On the surface, it seems odd to require associate-name, but I suppose that if it is a TBP or other procedure, you would just want to execute it once during the SELECT TYPE... perhaps.

Thanks!

Actually, the relevant difference is not that between variables and object designators, but that between simple names and general designators. In a sense, SELECT TYPE always requires an associate-name, but it allows you to syntactically omit specifying the name if there is an obvious default. If the selector expression is a simple name, then that name is that obvious default associate-name.

Why does SELECT TYPE need an associate-name? Your example is somewhat unusual in that it does nothing triangle-specific after determining that the shape is a triangle. [As such, it could have been implemented using the intrinsic function EXTENDS_TYPE_OF instead of a SELECT TYPE contruct.] A more typical example would either reference a type bound procedure specific to triangles (which we do not have in this example) or a component specific to triangles (in this case, the component points). To do this, we need a name whose static type or class is triangle. That name is the associate-name. The associate-name is effetively declared to be CLASS(triangle) in the block following the CLASS IS (triangle) statement and CLASS(shape) in the block following the CLASS DEFAULT statement.

The associate-name is the whole point of the SELECT TYPE construct. If you do not need an associated name with the appropriate properties, you can get by with EXTENDS_TYPE_OF and/or SAME_TYPE_AS.

-Kurt
0 Kudos
Reply