3

I want to use a function's parameter with attribute "value". It is an optional parameter and I want to use it when it has not been passed. I expect that there is a local variable associated with the optional parameter, because the optional paramter is passed by value and not by reference. But strange things occurr when I try to do it.

In the example below, the string "Hello" should be printed, but the contents of the character parameter "Str" seems to be empty.

module test_value_mod

    implicit none

    contains

    subroutine printStr(Str, AddTip)
        ! Declaration of parameters
        character(len=*), intent(in)    :: Str
        logical, optional, value        :: AddTip

        if (.not. present(AddTip)) AddTip = .False.

        write (*,*) 'Str: ', Str
        if (AddTip) write (*,*) 'Tip is printed.'
    end subroutine printStr

end module test_value_mod

program test_value_prog
    use test_value_mod

    implicit none

    call printStr('Hello')

end program test_value_prog

However, when I pass the charaacter length as another parameter, there is no problem:

module test_value_mod

    implicit none

    contains

    subroutine printStr(Str, LenStr, AddTip)
        ! Declaration of parameters
        integer, intent(in)             :: LenStr
        character(len=LenStr), intent(in)    :: Str

        logical, optional, value        :: AddTip

        if (.not. present(AddTip)) AddTip = .False.

        write (*,*) 'Str: ', Str
        if (AddTip) write (*,*) 'Tip is printed.'
    end subroutine printStr

end module test_value_mod

program test_value_prog
    use test_value_mod

    implicit none

    call printStr('Hello', len_trim('Hello'))

end program test_value_prog

I use gfortran 7.3.0. But if I compile with ifort 17.0.4, I get the following error for the two examples given above:

forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image              PC                Routine            Line        Source             
test_value_passin  0000000000402C64  Unknown               Unknown  Unknown
libpthread-2.17.s  00007EFDA90825E0  Unknown               Unknown  Unknown
test_value_passin  000000000040288D  test_value_mod_mp          15  test_value_passing.f08
test_value_passin  0000000000402A08  MAIN__                     29  test_value_passing.f08
test_value_passin  00000000004027CE  Unknown               Unknown  Unknown
libc-2.17.so       00007EFDA8CD1C05  __libc_start_main     Unknown  Unknown
test_value_passin  00000000004026E9  Unknown               Unknown  Unknown

Line 15 in "test_value_mod_mp" is: if (.not. present(AddTip)) AddTip = .False.

So, I think that the use of an optional paramter pased by value when it has not been actually provided, is invalid. But, however, gcc permits it, failing only if you provide another input paramter of type character of assumed length.

Could anybody clarify?

Antonio Serrano
  • 385
  • 2
  • 15
  • You can not use an argument that is not present in any way. You may only inquire its presence. I think we will have a duplicate. – Vladimir F Героям слава Jan 15 '19 at 12:03
  • Indeed, the `value` attribute does not loosen the restrictions on optional arguments. – francescalus Jan 15 '19 at 12:06
  • No, the GCC behaviour is not a bug. Your code is incorrect and anything can happen with such code, see https://en.wikipedia.org/wiki/Undefined_behavior I believe the linked answers and questions answer your problem adequately, that's why I applied the duplicate. But if others think they do not and the `value` bit is important enough to warrant a separate answer... But I do not think it is. – Vladimir F Героям слава Jan 15 '19 at 12:30
  • The behaviour of gfortran here isn't a bug. What you have given the compiler isn't valid Fortran code and in this case the compiler isn't obliged to work that out for itself. That said, here may be an option for your compiler to add checks at runtime for this error. – francescalus Jan 15 '19 at 12:30
  • @VladimirF Ok. My question has a very good answer in the second link that you have provided, but perhaps it is difficult to reach it because this problem can be described in may ways. – Antonio Serrano Jan 15 '19 at 12:32
  • That's why duplicates are useful, because they will point other persons who search to similar stuff as you to the right place. They certainly should not be deleted. – Vladimir F Героям слава Jan 15 '19 at 12:36

0 Answers0