/usr/share/doc/libcnf-dev/html/node60.html is in libcnf-dev 4.0-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<!--Converted with LaTeX2HTML 98.2 beta6 (August 14th, 1998)
original version by: Nikos Drakos, CBLU, University of Leeds
* revised and updated by: Marcus Hennecke, Ross Moore, Herb Swan
* with significant contributions from:
Jens Lippmann, Marek Rouchal, Martin Wilck and others -->
<HTML>
<HEAD>
<TITLE>Arguments</TITLE>
<META NAME="description" CONTENT="Arguments">
<META NAME="keywords" CONTENT="sun209">
<META NAME="resource-type" CONTENT="document">
<META NAME="distribution" CONTENT="global">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<LINK REL="STYLESHEET" HREF="sun209.css">
<LINK REL="next" HREF="node61.html">
<LINK REL="previous" HREF="node59.html">
<LINK REL="up" HREF="node57.html">
<LINK REL="next" HREF="node61.html">
</HEAD>
<BODY >
<BR> <HR>
<A NAME="tex2html844"
HREF="node61.html">
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next" SRC="next_motif.gif"></A>
<A NAME="tex2html842"
HREF="node57.html">
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up" SRC="up_motif.gif"></A>
<A NAME="tex2html836"
HREF="node59.html">
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous" SRC="previous_motif.gif"></A> <A HREF="sun209.html#stardoccontents"><IMG
ALIGN="BOTTOM" BORDER="0" SRC="contents_motif.gif"
ALT="252"></A>
<BR>
<B> Next:</B> <A NAME="tex2html845"
HREF="node61.html">Function Values</A>
<BR>
<B>Up:</B> <A NAME="tex2html843"
HREF="node57.html">VAX/VMS</A>
<BR>
<B> Previous:</B> <A NAME="tex2html837"
HREF="node59.html">Data Types</A>
<BR> <HR> <P>
<!--End of Navigation Panel-->
<H3><A NAME="SECTION000153300000000000000"></A><A NAME="vms_arg"></A>
<BR>
Arguments
</H3>
<P>
To understand how to pass arguments between VAX FORTRAN and VAX C programs, it
is necessary to understand the possible methods that VMS can use for passing
arguments and how each language makes use of them. VMS defines a procedure
calling standard that is used by all compilers written by DEC for the VMS
operating system. This is described in the ``Introduction to the VMS Run-Time
Library'' manual with additional information in the ``Introduction to VMS System
Services'' manual. If you have a third party compiler that does not conform to
this standard then you will not be able to mix the object code that it produces
with that from DEC compilers. There are three ways that an actual argument may
be passed to a subroutine. What is actually passed as an argument should always
be a longword. It is the interpretation of that longword that is where the
differences arise. Note the word <I>should</I> in the last but one sentence.
VAX C will occasionally generate an argument that is longer than one longword.
This is a violation of the VAX procedure calling standard. It causes no
problems for pure VAX C programs, but is a potential source of problems for
mixed language programs.
<P>
VAX FORTRAN passes all data types other than <TT>CHARACTER</TT> by reference,
<I>i.e.</I> the address of the variable or array is put in the argument list.
<TT>CHARACTER</TT> variables are passed by descriptor.
The descriptor contains the type and class of descriptor, the length of the
string and the address where the characters are actually stored.
<P>
VAX C uses call by value to pass all variables, constants (except string
constants), expressions, array elements, structures and unions that are actual
arguments of functions. It uses call by reference to pass whole arrays, string
constants and functions. VAX C never uses call by descriptor as a default
method of passing arguments.
<P>
To pass a VAX C variable of type <TT>double</TT> by value requires the use of two
longwords in the argument list and so is a violation of the VAX procedure
calling standard. The passing of a VAX C structure that is bigger that one
longword is a similar violation. It is always better to pass C structures by
reference, although this should not be a problem in practice since in the case
of a pure VAX C program, everything is handled consistently and in the case of
a mixture of FORTRAN and C, you would not normally pass variables by value
anyway.
<P>
In VAX FORTRAN, the default argument passing mechanism can be overridden by use
of the <TT>%VAL</TT>, <TT>%REF</TT> and <TT>%DESCR</TT> functions.
These functions are not portable and should be avoided whenever possible.
The only exception is that <TT>%VAL</TT> is used in Starlink software for
passing pointer variables.
In VAX C there is no similar way of ``cheating'' as there is in VAX FORTRAN;
however, this is not necessary as the language allows more flexibility itself.
For example, if you wish to pass a variable named <TT>x</TT> by reference rather
than by value, you simply put <TT>&x</TT> as the actual argument instead of
<TT>x</TT>.
To pass something by descriptor, you need to construct the appropriate
structure and pass the address of that. See the DEC manual ``Guide to VAX C''
for further details.
<P>
Since C provides more flexibility in the mechanism of passing arguments than
does FORTRAN, it is C that ought to shoulder the burden of handling the
different mechanisms. All numeric variables and constants, array elements,
whole arrays and function names should be passed into and out of C functions by
reference. Numeric expressions will be passed from VAX FORTRAN to VAX C by
reference and so the corresponding dummy argument in the C function should be
declared to be of type ``pointer to type''. When C has a constant or an
expression as an actual argument in a function call, it can only pass it by
value. VAX FORTRAN cannot cope with this and so in a VAX C program, all
expressions should be assigned to variables before being passed to a FORTRAN
routine.
<P>
Here are some examples to illustrate these points.
<P>
<A NAME="vms_f2c"></A>
<DIV ALIGN="CENTER">
Example
- Passing arguments from VAX FORTRAN to VAX C.
</DIV>
FORTRAN program:
<PRE>
PROGRAM FORT1
INTEGER A
REAL B
A = 1
B = 2.0
CALL C1( A, B )
END
</PRE>
C function:
<PRE>
void c1( int *a, float *b )
{
int x;
float y;
x = *a; /* x is now equal to 1 */
y = *b; /* y is now equal to 2.0 */
printf( "x = %d\n", x );
printf( "y = %f\n", y );
}
</PRE>
<P>
In this first example, a FORTRAN program passes an <TT>INTEGER</TT> and
<TT>REAL</TT> variable to a C function.
The values of these arguments are then assigned to two local
variables. They could just as well have been used directly in the function by
referring to the variables <TT>*a</TT> and <TT>*b</TT> instead of
assigning their values to the local variables <TT>x</TT> and <TT>y</TT>.
Since the VAX FORTRAN program passes the actual arguments by reference, the
dummy arguments used in the declaration of the VAX C function should be a
pointer to the variable that is being passed.
<P>
Now an example of calling a VAX FORTRAN subroutine from VAX C.
<P>
<A NAME="vms_c2f"></A>
<DIV ALIGN="CENTER">
Example
- Passing arguments from VAX C to VAX FORTRAN.
</DIV>
C main program:
<PRE>
main()
{
int i = 2; /* Declare i and initialize it. */
void fort2( int *i ); /* Declare function fort2. */
fort2( &i ); /* Call fort2. */
}
</PRE>
FORTRAN subroutine:
<PRE>
SUBROUTINE FORT2( I )
INTEGER I
PRINT *,I
END
</PRE>
<P>
The VAX C main function declares and initializes a variable, <TT>i</TT>, and
declares a function <TT>fort2</TT>.
It calls <TT>fort2</TT>, passing the address of the variable <TT>i</TT> rather
than its value, as this is what the VAX FORTRAN subroutine will be expecting.
<P>
As we have seen, the case of scalar numeric arguments is fairly
straightforward.
However, the passing of <TT>CHARACTER</TT> variables between VAX FORTRAN
and VAX C is more complicated. VAX FORTRAN passes <TT>CHARACTER</TT> variables
by descriptor and VAX C must handle these descriptors.
Furthermore, there is the point that FORTRAN deals with fixed-length,
blank-padded strings, whereas C deals with variable-length, null-terminated
strings. It is also worth noting that VAX/VMS machines handle
<TT>CHARACTER</TT> arguments in a manner which is different from the usual Unix
way.
The simplest possible example of a <TT>CHARACTER</TT> argument is given here
in all of its gory detail.
You will be pleased to discover that this example is purely for illustration.
The important point is that it is different from the Sun example and, anyway,
the
<A HREF="node18.html#f77_cfromf">F77 macros</A>
hide all of these
differences from the programmer, thereby making the code portable.
<P>
<A NAME="vms_char"></A>
<DIV ALIGN="CENTER">
Example
- Passing character arguments from VAX FORTRAN to
VAX C.
</DIV>
FORTRAN program:
<PRE>
PROGRAM FORT3
CHARACTER STR*20
CALL C3( STR )
PRINT *,STR
END
</PRE>
C function:
<PRE>
#include <descrip.h> /* VMS Descriptors */
#include <stdio.h> /* Standard I/O functions */
void c3( struct dsc$descriptor_s *fortchar )
{
int i; /* A loop counter */
char *string = "This is a string"; /* A string to be printed */
/* Copy the string to the function argument */
strncpy( fortchar->dsc$a_pointer, string, fortchar->dsc$w_length );
/* Pad the character argument with trailing blanks */
for( i = strlen( string ) ; i < fortchar->dsc$w_length ; i++ )
fortchar->dsc$a_pointer[i] = ' ';
}
</PRE>
<P>
The second variable declaration in the C subprogram declares a local variable
to be a string and initializes it. This string is then copied to the storage
area that the subprogram argument points to, taking care not to copy more
characters than the argument has room for. Finally any remaining space in the
argument is filled with blanks, the null character being overwritten. You
should always fill any trailing space with blanks in this way. What should
definitely not be done is to modify the descriptor to indicate the number of
non blank characters that it now holds. The VAX FORTRAN compiler will not
expect this to happen and it is likely to cause run-time errors. See the DEC
manual ``Guide to VAX C'' for more details of handling descriptors in VAX C.
<P>
If an actual argument in a VAX FORTRAN routine is an array of characters, rather
than just a single character variable, the descriptor that describes the data
is different. It is defined by the macro <TT>dsc$descriptor_a</TT> instead of
<TT>dsc$descriptor_s</TT>. This contains extra information about the number of
dimensions and their bounds; however, this can generally be ignored since the
first part of the <TT>dsc$descriptor_a</TT> descriptor is the same as the
<TT>dsc$descriptor_s</TT> descriptor. This extra information can be unpacked from the
descriptor, however, to do so would lead to non-portable code. It is generally
better to use the address of the array that is passed in the descriptor and to
pass any array dimensions as separate arguments. The C subroutine then has all
of the information that it requires and can handle the data as an array or by
using pointers, as the programmer sees fit. See example <A HREF="node21.html#f77_arbary"><IMG ALIGN="BOTTOM" BORDER="1" ALT="[*]" SRC="cross_ref_motif.gif"></A> for
an illustration of this.
<P>
<BR> <HR>
<A NAME="tex2html844"
HREF="node61.html">
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next" SRC="next_motif.gif"></A>
<A NAME="tex2html842"
HREF="node57.html">
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up" SRC="up_motif.gif"></A>
<A NAME="tex2html836"
HREF="node59.html">
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous" SRC="previous_motif.gif"></A> <A HREF="sun209.html#stardoccontents"><IMG
ALIGN="BOTTOM" BORDER="0" SRC="contents_motif.gif"
ALT="252"></A>
<BR>
<B> Next:</B> <A NAME="tex2html845"
HREF="node61.html">Function Values</A>
<BR>
<B>Up:</B> <A NAME="tex2html843"
HREF="node57.html">VAX/VMS</A>
<BR>
<B> Previous:</B> <A NAME="tex2html837"
HREF="node59.html">Data Types</A>
<BR> <HR> <P>
<!--End of Navigation Panel-->
<ADDRESS>
<I>CNF and F77 Mixed Language Programming -- FORTRAN and C<BR>Starlink User Note 209<BR>P.M. Allan<BR>A.J. Chipperfield<BR>R.F. Warren-Smith<BR>19 January 2000<BR>E-mail:<A HREF="mailto:ussc@star.rl.ac.uk">ussc@star.rl.ac.uk</A></I>
</ADDRESS>
</BODY>
</HTML>
|