2011-01-24 41 views
3

如果我有此代碼傳遞字符串作爲參數時虛設已經規定長度

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 

因爲「foo2的」它不會編譯沒有長度爲20,並且編譯器抱怨

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

如何在不修改子程序dummy len規範的情況下使這件事情起作用?是否強制要求一箇中間變量以相同的長度聲明並在通話時傳遞?

回答

2

對我來說似乎符合標準的行爲。

的Fortran 2003,12.4.1.2與虛設數據有關的實際參數對象

如果標量僞參數是 類型默認字符的,的 長度LEN的僞參數應小於 或等於到實際的 參數的長度。虛擬參數變爲 與實際參數的最左邊的len 字符相關聯。

然而gfortran剛剛上升的警告消息

警告:在(1)

實際參數比虛參 '名稱' 的短(4/20)的字符長度這似乎英特爾Fortran編譯器在這方面更符合標準。所以中間變量可能是唯一的選擇。

或者實際上只是聲明一個變量是選項,因爲你的代碼中沒有一個變量。你有字面常量。無論如何,硬編碼值並不是一個好主意。 =)

6

標準語言可能很難理解。我讀了@kemiisto引用的條款,要求長度爲(dummy arg) <= length(實際的參數)。這裏長度爲(dummy arg) = 20length (actual arg) = 4,所以長度爲(dummy arg) > length (actual arg),這是條款所不允許的。該條款談到截斷實際匹配虛擬,如果需要,不填充空白。

如果你用character(len = *)代替character(len = 20)這個代碼會起作用,因爲你不想修改僞參數規範的長度,是否有問題?

+0

問題是具有字符(len = 20)的例程位於我不應該修改的代碼的一部分中。 – 2011-01-25 10:13:42

1

發生此錯誤的原因是您的方法允許讀取/寫入最多len=20個字符到虛擬參數name。你的字符串文字少於這個數量,你的編譯器會提醒你注意這個事實。即使它被宣佈intent(in)你可以讀取超出實際參數長度,會導致訪問衝突等

你或許應該堅持len=*與虛擬參數,並確定這是多少個字符安全閱讀時使用lenlen_trim /寫。

或者如果您必須保留len=20,則應使用臨時變量將值傳遞到該方法。或者像"hello"//repeat(" ", 15)這類醜陋的東西。

相關問題