Passing a string inline to a subroutine call, where the parameter has defined length, gives unexpected results

我是研究僧i 提交于 2019-12-01 20:11:38

I think your code is non-conforming. Section 12.4.1.1 of the Fortran 95 standard states:

12.4.1.1 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.

The problem is that bar requires a string of length 50 (cf. character(len=LCHARS), intent(in) :: str), whereas the string you are passing it is only of length 6. Compiling this with

ifort -Warn all,nodec,interfaces,declarations -gen_interfaces -check all -std test.f90

produces the error

forrtl: severe (408): fort: (18): Dummy character variable 'STR' has length 50 which is greater then actual variable length 6

As far as know all Fortran arguments are passed by reference. Behind the scenes, what the function bar gets is a pointer to the start of the string str and an extra parameter whose value is the length of the string. So bar will take 50 characters worth of memory, starting at the beginning of str, and print that to screen. Since the string that you pass is only 6 characters long, the remaining 44 characters will be whatever is in the next bit of memory after "foobar", which will differ at run time or depending on the compiler you use.

Argument passing is compiler-dependent, as long as the requirements of the standard are fulfilled, but generally, a CHARACTER(len=*) dummy argument will have an interface something like

void foo(char *s, int len)

and in the implementation of the foo procedure the hidden len argument is used as the string length. OTOH, for a CHARACTER(len=somevalue) argument the hidden len argument is either ignored or not passed at all, and the code for the procedure assumes that somevalue is the correct length of the string.

As you have seen, you should never use anything but LEN=* unless you really know what you're doing and can quote chapter and verse from the standard to explain why.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!