passing a string as an argument when the dummy has specified length

16,232

Solution 1

Standard language can be hard to understand. I read the clause cited by @kemiisto as requiring length (dummy arg) <= length (actual arg). Here length (dummy arg) = 20 and length (actual arg) = 4, so length (dummy arg) > length (actual arg), which is not allowed by the clause. The clause talks about truncating the actual to match the dummy, if needed, not padding it with blanks.

The code will work if you replace character(len = 20) with character(len = *) Is there a problem with this since you didn't want to modify the length of the dummy argument specification?

Solution 2

Seems to me like standard compliant behavior.

Fortran 2003, 12.4.1.2 Actual arguments associated with dummy data objects

If a scalar dummy argument is of type default character, the length len of the dummy argument shall be less than or equal to the length of the actual argument. The dummy argument becomes associated with the leftmost len characters of the actual argument.

However gfortran just rise a warning message

Warning: Character length of actual argument shorter than of dummy argument 'name' (4/20) at (1)

It seems that Intel Fortran compiler is more standard compliant in that respect. So intermediate variable is probably the only option.

Or actually just declaring a variable is option because you do not have one in your code. You have literal constant. Hard-coded values are not a good idea anyway. =)

Solution 3

The reason this error occurs is your method is allowed to read/write up to len=20 characters to the dummy argument name. Your string literal is less than this amount and your compiler is alerting you to this fact. Even though it is declared intent(in) you could read beyond the actual argument length and cause an access violation, etc.

You should probably stick to len=* with dummy arguments and use len or len_trim when determining how many characters it is safe to read/write.

Or if you must keep the len=20, you should use a temporary variable used to pass values into that method. Or something uglier like "hello"//repeat(" ", 15).

Share:
16,232

Related videos on Youtube

Stefano Borini
Author by

Stefano Borini

Updated on June 04, 2022

Comments

  • Stefano Borini
    Stefano Borini almost 2 years

    if I have this code

    module test
    contains
       subroutine xx(name)
          character(len=20), intent(in), optional :: name
    
          if (present(name)) then
             print *, name
          else
             print *, "foo"
          endif
       end subroutine
    end module
    program x
       use test
    
       call xx()
       call xx("foo2")
    end program
    

    It will not compile since "foo2" is not of length 20, and the compiler complains

    test.f90(17): error #7938: Character length argument mismatch.   ['foo2']
       call xx("foo2")
    -----------^
    

    How can I make this thing work, without modifying the subroutine dummy len specification ? Is it mandatory to have an intermediate variable declared with the same length and pass that at call time ?

  • Stefano Borini
    Stefano Borini about 13 years
    the problem is that the routine with character(len=20) is in a part of the code I am not supposed to modify.
  • M. S. B.
    M. S. B. about 13 years
    Then I suggest writing a "glue" function that transforms its arguments to character (len=20) and applying this function to any argument of xx that might not be long enough: call xx (makelen20 ("foo2"))

Related