![]() ![]() ![]() ![]() Next: Telling the Make system Up: Data Types and Sizes Previous: Data Types and Sizes Contents Fortran Thorn WritersCactus provides the data types CCTK_POINTER and CCTK_POINTER_TO_CONST for use in Fortran code to declare a pointer passed from C. For example, the variable cctkGH is of the type CCTK_POINTER. The data type CCTK_STRING is, in Fortran, also an opaque type; it corresponds to a C pointer, and one has to use the function CCTK_FortranString to convert it to a Fortran string, or the CCTK_Equals to compare it to a Fortran String. Since the data types, integer in Fortran and int in C, may be differentpart142, many routines that can be called from both, C and Fortran, take arguments of the type CCTK_INT. This type can be different from the type integer. Fortran does not convert routine arguments automatically, and it is, therefore, necessary to pay attention to the exact argument types that a routine expects, and to convert between integer and CCTK_INT, accordingly. Currently, most flesh functions take integer arguments, while all aliased functions take CCTK_INT arguments.
NOTE: If you make errors in passing Fortran arguments, and if there are no interfaces (``prototypes'') available for the routines that are called, then the compiler cannot detect these errors. Be careful, when you write Fortran code yourself, consider placing routines in modules, which implicitly define interfaces for all contained routines. There are two convenient ways to convert between these types. An easy way, is to define parameters or to declare variables of the desired type, assign a value to these parameters or variables, and then pass the parameter or value. This makes for very readable code, since the name of the parameter or variable serves as additional documentation:
CCTK_INT, parameter : jtwo = 2 integer :: vindex_gxx, vindex_kxx CCTK_INT :: syncvars(jtwo) call CCTK_VarIndex (vindex_gxx, "ADMBase::gxx") call CCTK_VarIndex (vindex_kxx, "ADMBase::kxx") syncvars(1) = vindex_gxx syncvars(2) = vindex_kxx call CCTK_SyncGroupsI (cctkGH, jtwo, syncvars) (You have probably seen the strange Fortran convention, where people introduce constants named zero or two--it is a convenient way to make sure that the constant has the correct type.) Another possibility are explicit type conversions. They can rather easily be added to existing code:
! Boilerplate code to determine type kinds integer, parameter :: izero = 0 ! A dummy variable of type integer CCTK_INT, parameter :: jzero = 0 ! A dummy variable of type CCTK_ITN integer, parameter :: ik = kind (izero) ! The kind of "integer" integer, parameter :: jk = kind (jzero) ! The kind of "CCTK_INT" integer :: syncvars(2) call CCTK_VarIndex (syncvars(1), "ADMBase::gxx") call CCTK_VarIndex (syncvars(2), "ADMBase::kxx") call CCTK_SyncGroupsI (cctkGH, int(2,jk), int(syncvars,jk)) Fortran distinguishes between different integer kinds. These kinds are what is different between integer and CCTK_INT. The expression int(EXPR,KIND) converts EXPR to an integer of kind KIND. Above, we use the convention that the prefix i denotes things having to do with integer, and the prefix j denotes CCTK_INT. Note that we declare the array syncvars with the type that is necessary to set its values. Type conversions are only possible if variables are read, not when they are written to.
![]() ![]() ![]() ![]() Next: Telling the Make system Up: Data Types and Sizes Previous: Data Types and Sizes Contents |