Hi,
Dan Packman writes:
> Some time ago I asked some leading questions about adding a string primitive
> to NetCDF and complained a bit about the redundant call requirements on
> fortran for the current "CHAR" data type. The latter can be seen, for
> example, in the Get Attribute Value call:
>
> in C: ncattget(cdfid,varid,name,value);
>
> in Fortran: call ncagt(cdfid,varid,attnam,values,rcode)
> call ncagtc(cdfid,varid,attnam,string,lenstr,rcode)
>
> Ok, I'll admit that for proper fortran, data *types* must agree across calls
> so one needs two calls to separate out the character versus the nonchar
> arguments. The totally unecessary part is the "lenstr" variable. The called
> routine can do a "len(string)" to determine this information if needed.
I guess I disagree. In Fortran, the string argument might be a vector or an
array, since netCDF supports vector attributes and multidimensional array
variables of various types, including character. Notice that if the
variable STRING is declared in any of the following ways
CHARACTER*1 S(100)
CHARACTER*10 T(10)
CHARACTER*100 U
and then used as an argument (corresponding to the formal parameter ARG, for
example) in a Fortran function or subroutine, the value of LEN(ARG) will be
1, 10, or 100, respectively, even though in each case the user is passing
space for 100 characters. Hence the value of LEN(ARG) is useless to
determine whether enough space has been allocated for the characters to be
returned.
> If not, it can merely assume that enough space is available (like the c
> code), and deal with the variable as "character*(*) string".
The string-length parameter is in the get-attribute and get-value calls for
symmetry with the put-attribute and put-value calls, where it is required
because the value returned by the LEN() function doesn't necessarily
correspond with the user's intent in the case of character string arrays.
It would have been arguably simpler to leave the string length parameters
out of the get calls and not check for whether the user provided enough
space, but that would be a disservice in the case of attributes, where for
safety the user would otherwise have to precede every get-attribute call
with an attribute-inquire call to make sure the attribute value wasn't too
large for the allocated space (as is necessary for the C interface). With
the current Fortran interface, only one call is needed, and the user can
find out from the results of the call whether the attribute value was larger
than the space allocated. The string-length parameter is intended to be the
space allocated for an attribute value, not the value returned by the LEN()
function, which may be smaller in the case of a character array. The
current documentation probably doesn't make this intended meaning of the
string-length argument clear enough.
> The NetCDF User's Guide (vers 1.11) on page 92 seems to imply that the
> len function is not part of the f77 standard. Fortran does indeed support
> the concept of variable length character strings. Instead of the object
> having a well defined termination as in c (a null), there is a character
> count implicit in each character string that is available to the user
> via a len() built-in function.
I don't think character*(*) variables are variable-length character strings,
since that type declaration is only valid for formal parameters, and the
strings passed in that correspond to it are ultimately fixed length. The
length returned by the LEN() function is the static length declared for a
character variable. In the following
CHARACTER*100 C
C = 'ABCDE'
PRINT *, LEN(C)
the value returned by LEN(C) is 100 (the static length) not 5 (the dynamic
length). And if you write a function that tries to determine the dynamic
length of a string by stripping off trailing blanks, it will give you the
wrong answer for Fortran strings that are assigned values with trailing
blanks. That's the basis of my statement that Fortran doesn't support true
variable-length strings.
--Russ