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

Issue with SELECT CASE and null CASE block

jimdempseyatthecove
Honored Contributor III
992 Views

In the following code EDIT: using ifort

 

    J = FP_CLASS(pTether%pFiniteSolution%ELBD)
  SELECT CASE (J)
    CASE (0)
    call DOSTOP('TNSMKS FOR_K_FP_SNAN')
    CASE(1)
    call DOSTOP('TNSMKS FOR_K_FP_QNAN')
    CASE(2)
    call DOSTOP('TNSMKS FOR_K_FP_POS_INF')
    CASE(3)
    call DOSTOP('TNSMKS FOR_K_FP_NEG_INF')
    CASE(4)
	! OK - FOR_K_FP_POS_NORM
    CASE(5)
	! OK - FOR_K_FP_NEG_NORM
	CASE(6)
    write(*,*) 'TNSMKS FOR_K_FP_POS_DENORM'
    CASE(7)
    write(*,*) 'TNSMKS FOR_K_FP_NEG_DENORM'
    CASE(8)
	! OK - FOR_K_FP_POS_ZERO
    CASE(9)
	! OK - FOR_K_FP_NEG_ZERO        ? Saw this with    0. * 9.900990099009901E-003
	!                               ? could have been -0. * 9.900990099009901E-003
    CASE DEFAULT
    call DOSTOP('TNSMKS FOR_K_FP_unknown')
  END SELECT    

 

I have null/empty case blocks for 4, 5, 8, and 9.

These are cases I wish to ignore. However, case(8) in the observed case, falls through into case default.

Note, if I place something innocuous in the null cases, the select case behaves properly.

 

    J = FP_CLASS(pTether%pFiniteSolution%ELBD)
  SELECT CASE (J)
    CASE (0)
    call DOSTOP('TNSMKS FOR_K_FP_SNAN')
    CASE(1)
    call DOSTOP('TNSMKS FOR_K_FP_QNAN')
    CASE(2)
    call DOSTOP('TNSMKS FOR_K_FP_POS_INF')
    CASE(3)
    call DOSTOP('TNSMKS FOR_K_FP_NEG_INF')
    CASE(4)
	! OK - FOR_K_FP_POS_NORM
        J = 0
    CASE(5)
	! OK - FOR_K_FP_NEG_NORM
        J = 0
	CASE(6)
    write(*,*) 'TNSMKS FOR_K_FP_POS_DENORM'
    CASE(7)
    write(*,*) 'TNSMKS FOR_K_FP_NEG_DENORM'
    CASE(8)
	! OK - FOR_K_FP_POS_ZERO
        J = 0
    CASE(9)
	! OK - FOR_K_FP_NEG_ZERO        ? Saw this with    0. * 9.900990099009901E-003
        J = 0
	!                               ? could have been -0. * 9.900990099009901E-003
    CASE DEFAULT
    call DOSTOP('TNSMKS FOR_K_FP_unknown')
  END SELECT    

 

Intel® Fortran Compiler – toolkit version: 2023.0.0, extension version 23.0.0070.16, Package ID: w_oneAPI_2023.0.0.25839

Jim Dempsey

 

0 Kudos
14 Replies
FortranFan
Honored Contributor II
981 Views

Jim,

You know the drill, Intel support team will want a reproducer but your original post does not provide one:

module m
contains
   subroutine sub( J )
      integer, intent(in) :: J
      SELECT CASE (J)
         CASE (0)
            call DOSTOP('TNSMKS FOR_K_FP_SNAN')
         CASE(1)
            call DOSTOP('TNSMKS FOR_K_FP_QNAN')
         CASE(2)
            call DOSTOP('TNSMKS FOR_K_FP_POS_INF')
         CASE(3)
            call DOSTOP('TNSMKS FOR_K_FP_NEG_INF')
         CASE(4)
            ! OK - FOR_K_FP_POS_NORM
         CASE(5)
            ! OK - FOR_K_FP_NEG_NORM
         CASE(6)
            write(*,*) 'TNSMKS FOR_K_FP_POS_DENORM'
         CASE(7)
            write(*,*) 'TNSMKS FOR_K_FP_NEG_DENORM'
         CASE(8)
            ! OK - FOR_K_FP_POS_ZERO
         CASE(9)
            ! OK - FOR_K_FP_NEG_ZERO        ? Saw this with    0. * 9.900990099009901E-003
            !                               ? could have been -0. * 9.900990099009901E-003
         CASE DEFAULT
            call DOSTOP('TNSMKS FOR_K_FP_unknown')
      END SELECT
   end subroutine 
   subroutine DOSTOP( s )
      character(len=*), intent(in) :: s
      print *, s
   end subroutine 
end module
   use m
   call sub( 8 )
end 
C:\temp>ifort /standard-semantics p.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.8.0 Build 20221119_000000
Copyright (C) 1985-2022 Intel Corporation.  All rights reserved.

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

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

C:\temp>p.exe

C:\temp>
0 Kudos
Steve_Lionel
Honored Contributor III
978 Views

I can't reproduce the behavior you described. I tried this variant as a MRE:

 

   do j=0,9
   print *, j
  SELECT CASE (J)
    CASE (0)
    call DOSTOP('TNSMKS FOR_K_FP_SNAN')
    CASE(1)
    call DOSTOP('TNSMKS FOR_K_FP_QNAN')
    CASE(2)
    call DOSTOP('TNSMKS FOR_K_FP_POS_INF')
    CASE(3)
    call DOSTOP('TNSMKS FOR_K_FP_NEG_INF')
    CASE(4)
	! OK - FOR_K_FP_POS_NORM
    CASE(5)
	! OK - FOR_K_FP_NEG_NORM
	CASE(6)
    write(*,*) 'TNSMKS FOR_K_FP_POS_DENORM'
    CASE(7)
    write(*,*) 'TNSMKS FOR_K_FP_NEG_DENORM'
    CASE(8)
	! OK - FOR_K_FP_POS_ZERO
    CASE(9)
	! OK - FOR_K_FP_NEG_ZERO        ? Saw this with    0. * 9.900990099009901E-003
	!                               ? could have been -0. * 9.900990099009901E-003
    CASE DEFAULT
    call DOSTOP('TNSMKS FOR_K_FP_unknown')
  END SELECT   
end do
end 
subroutine dostop (s)
character(*) :: s
print *, s
end subroutine dostop

 

When I built and ran this I got:

 

D:\Projects>ifort t.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.8.0 Build 20221119_000000
Copyright (C) 1985-2022 Intel Corporation.  All rights reserved.

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

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

D:\Projects>t.exe
           0
 TNSMKS FOR_K_FP_SNAN
           1
 TNSMKS FOR_K_FP_QNAN
           2
 TNSMKS FOR_K_FP_POS_INF
           3
 TNSMKS FOR_K_FP_NEG_INF
           4
           5
           6
 TNSMKS FOR_K_FP_POS_DENORM
           7
 TNSMKS FOR_K_FP_NEG_DENORM
           8
           9

 

At first I thought that the syntax rule in the standard was wrong for a case construct in that it did not show the block as optional. But the syntax term for block itself allows it to be empty.

0 Kudos
jimdempseyatthecove
Honored Contributor III
934 Views

Steve, maybe it is an ifort version issue. Yours is 2021.8.0 mine is 2023.0.0

Jim Dempsey

0 Kudos
Steve_Lionel
Honored Contributor III
921 Views

There is no ifort version 2023.0.0. 2021.8.0 is the ifort in the current 2023.0.0 oneAPI release. ifx 2023.0.0 has the same correct behavior.

Show me a command line session building and running the complete program I posted above. Or, show me a complete program that demonstrates the behavior including build and run output.

0 Kudos
jimdempseyatthecove
Honored Contributor III
892 Views

On my first post, at bottom, I listed the compiler identifier as displayed in the cmd window:

 

Intel® Fortran Compiler – toolkit version: 2023.0.0, extension version 23.0.0070.16, Package ID: w_oneAPI_2023.0.0.25839

Yours shows:

Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.8.0 Build 20221119_000000

 

Hmmm......

The output I listed above for me came from  MS VS 2019 Help | About.

When I issue ifort /help I get

Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.8.0 Build 20221119_000000

 

The versioning that MS VS is reporting does not report the same as the command line (for the same compiler).

 

I can't account for why the posted code behaves differently on your system...

But wait, there's more...

In my build, I use fpp. In the code I posted was post fpp. The actual code segment has:

#ifdef _DEBUG
    J = FP_CLASS(ELBD)
  SELECT CASE (J)
    CASE (0)
    call DOSTOP('TNSMKS FOR_K_FP_SNAN')
    CASE(1)
    call DOSTOP('TNSMKS FOR_K_FP_QNAN')
    CASE(2)
    call DOSTOP('TNSMKS FOR_K_FP_POS_INF')
    CASE(3)
    call DOSTOP('TNSMKS FOR_K_FP_NEG_INF')
    CASE(4)
	! OK - FOR_K_FP_POS_NORM
    CASE(5)
	! OK - FOR_K_FP_NEG_NORM
	CASE(6)
#if 0
    call DOSTOP('TNSMKS FOR_K_FP_POS_DENORM')
#else
    write(*,*) 'TNSMKS FOR_K_FP_POS_DENORM'
#endif	
    CASE(7)
#if 0
    call DOSTOP('TNSMKS FOR_K_FP_NEG_DENORM')
#else
    write(*,*) 'TNSMKS FOR_K_FP_NEG_DENORM'
#endif	
    CASE(8)
	! OK - FOR_K_FP_POS_ZERO
    CASE(9)
	! OK - FOR_K_FP_NEG_ZERO        ? Saw this with    0. * 9.900990099009901E-003
	!                               ? could have been -0. * 9.900990099009901E-003
    CASE DEFAULT
    call DOSTOP('TNSMKS FOR_K_FP_unknown')
  END SELECT    
#endif

Jim Dempsey

 

 

 

0 Kudos
Steve_Lionel
Honored Contributor III
875 Views

What you see in Visual Studio is the integration version, not the compiler version. 

I have an idea I want to try out - stay tuned.

0 Kudos
andrew_4619
Honored Contributor II
868 Views

Jim, the IDE versioning is very confusing, I have noted this before. If you build  in VS you see the correct Fortran version in the output window a la "Compiling with Intel® Fortran Compiler Classic 2021.7.0 [Intel(R) 64]..." in my case. 

Also "Tools>Options> Intel Compilers....>IFORT.....>Compilers" gives all the versions and package versions etc.

0 Kudos
Steve_Lionel
Honored Contributor III
854 Views

Idea didn't pan out. I'll repeat my request to provide a complete example that demonstrates the problem, including all commands used to build it. Or you could try the program I posted.

My best guess is that you're misinterpreting the behavior.

0 Kudos
jimdempseyatthecove
Honored Contributor III
837 Views

>>My best guess is that you're misinterpreting the behavior.

How?

CASE(J), with J==8, fell through to CASE DEFAULT  with the result of making the CALL to DOSTOP

 

What happens for you if you initialize J via

 

var = 0.0

J = FP_CLASS(var)

...

replace call DOSTOP('...') with STOP '...'

 

Jim

 

0 Kudos
Steve_Lionel
Honored Contributor III
828 Views

I'm not going to discuss this further without a full example, build command and output.

0 Kudos
Steve_Lionel
Honored Contributor III
734 Views

@jimdempseyatthecove do you have a full test case yet? Or have you found the problem elsewhere?

0 Kudos
JohnNichols
Valued Contributor III
723 Views

Seems to work both ways.  

!  Console3.f90
    !
    !  FUNCTIONS:
    !  Console3 - Entry point of console application.
    !

    !****************************************************************************
    !
    !  PROGRAM: Console3
    !
    !  PURPOSE:  Entry point for the console application.
    !
    !****************************************************************************

    module m
    implicit none
    
    
   real, parameter :: pi = 3.1415926536  
   real, parameter :: e = 2.7182818285 
    contains
    
         
   subroutine show_consts()          
      print*, "Pi = ", pi          
      print*,  "e = ", e     
   end subroutine show_consts 
   
   
    subroutine sub( J )
    implicit none 
    integer, intent(in) :: J
    SELECT CASE (J)
    CASE (0)
        call DOSTOP('TNSMKS FOR_K_FP_SNAN')
    CASE(1)
        call DOSTOP('TNSMKS FOR_K_FP_QNAN')
    CASE(2)
        call DOSTOP('TNSMKS FOR_K_FP_POS_INF')
    CASE(3)
        call DOSTOP('TNSMKS FOR_K_FP_NEG_INF')
    CASE(4)
    
    
    CASE(5)
    CASE(6)
        write(*,*) 'TNSMKS FOR_K_FP_POS_DENORM'
    CASE(7)
        write(*,*) 'TNSMKS FOR_K_FP_NEG_DENORM'
    CASE(8)
        call DOSTOP('TNSMKS FOR_K_FP_unknown')
    
        ! OK - FOR_K_FP_POS_ZERO
    CASE(9)
        ! OK - FOR_K_FP_NEG_ZERO        ? Saw this with    0. * 9.900990099009901E-003
        !                               ? could have been -0. * 9.900990099009901E-003
        CASE DEFAULT
        call DOSTOP('TNSMKS FOR_K_FP_unknown  AA')
    END SELECT
    end subroutine


    subroutine DOSTOP( s )
    implicit none
    character(len=*), intent(in) :: s
    print *, s
    end subroutine
    end module


    program Console3
    use m
    
    implicit none
    integer j
    
    j = 0
    call show_consts()
    do 100 j = 1,15
    print *, j
    call sub( j )
100 end do    


    end program Console3

 

0 Kudos
jimdempseyatthecove
Honored Contributor III
703 Views

Ok, I can't account for the observation I had. Thanks all for the time you've spent on this.

Jim Dempsey

 

0 Kudos
JohnNichols
Valued Contributor III
689 Views

Jim:

Over many years, you have provided answers to a lot of my questions, a lot more time than I took to look at this interesting little problem.  

It is just part of being a friend and I enjoy our friendship, so thank you

John

0 Kudos
Reply