.. ############################################################################ .. File : doc/conventions.rst .. ############################################################################ ************ Conventions ************ Since the C++ and Fortran binding code are generated by SWIG-Fortran, most conventions are based on its defaults and built-in wrappers as described in `the SWIG+Fortran manual page`. This section attempts to describe all conventions used by Flibcpp that may be ambiguous to either a C++ or Fortran user. Since Flibcpp's target audience is Fortran users, the library tries to follows existing Fortran conventions, and this document attempts to remain true to the official Fortran nomenclature as described in the ISO standards. .. _the SWIG+Fortran manual page: https://github.com/swig-fortran/swig/blob/master/Doc/Manual/src/Fortran.md Basic types ============== The C++ standard library features many numeric classes and functions that take a template parameter corresponding to the type of a single element used by the class or algorithm. All such classes or functions that Flibcpp includes are templated on: - 32-bit integers (``integer(4)`` or ``integer(C_INT32_T)``), with a suffix of ``Int4`` where applicable; - 64-bit integers (``integer(8)`` or ``integer(C_INT64_T)``), with a suffix of ``Int8`` where applicable; and - 64-bit reals (``real(8)`` or ``real(C_DOUBLE)``), with a suffix of ``Real8`` where applicable. In general, most templated C++ functions use Fortran generic procedures to allow a single procedure name to operate on multiple types, and only the derived types (such as ``VectorInt4``) require the suffix. Error handling ============== Some modules support error handling for checking input values. In all cases, the error status and a message can be accessed and cleared through the main ``flc`` module:: use flc, only : ierr, get_serr ! if (ierr /= 0) then write(1,*) "Error", ierr, ":", get_serr() ! Reset the error flag to indicate that the error has been successfully ! handled. ierr = 0 fi Since errors do not immediately exit, it is up to the application code to check for and clear them. Failing to clear the error code may cause the application to exit on a subsequent Flibcpp procedure call. .. _conventions_indexing: Indexing ======== C and C++ use the convention that 0 corresponds to the first element in an array: specifically, it indicates an *offset* of zero from the array's beginning. In Fortran, the convention is for the first element to have an index of 1, so Flibcpp has the same convention. This convention makes native array integration straightforward. For example, when the :ref:`modules_algorithm_binary_search` algorithm is used with any value ``val`` in the sorted array ``arr``, the following logical expression will be true:: arr(binary_search(arr, val)) == val An additional convention Flibcpp uses is for an invalid index to have a value of zero. Thus, the :ref:`modules_algorithm_binary_search` algorithm returns zero if asked to find an element that's not present. Derived type behavior ===================== The derived types defined by Flibcpp are all "proxy" objects that operate on *pointers* to C++-owned objects. Some derived type values (i.e. class instances) will "own" the associated data, while some will merely reference data owned by other C++ objects. .. note:: Memory management in SWIG-Fortran-generated code is unintuitive and could change. If you have feedback, please contact the author. Construction ------------ Although Fortran separates the processes of allocation and initialization, C++ combines them into the single act of *construction*. Thus the proxy objects in Flibcpp can either be in an unassigned, deallocated state or in an allocated and internally consistent state. Each derived type, such as the :ref:`modules_string_type`, is constructed using a *module procedure interface* with the same name as the type. This procedure, defined in the same module as the derived type, is a ``function`` that returns a "constructed" type:: use flc_string, only : String type(String) :: s s = String() Most classes have more than one constructor (i.e. procedure interface) that gives the object a more substantial initial state. For example, numeric vectors can be constructed directly from a Fortran array:: use flc_vector, only : Vector => VectorInt4 type(Vector) :: v, v2 v = Vector([1, 2, 3, 5, 8, 13]) Assignment ---------- SWIG-Fortran, and consequently Flibcpp, defines assignment operators for its types that control memory ownership. Assignment for these types can be grouped into two categories: assignment directly from a Flibcpp function return value, and assignment from an existing Flibcpp derived type value. Flibcpp (or any other SWIG-Fortran) wrapper code sets the correct ownership flag on a return value: non-owning for raw pointers and references; owning for return-by-value. When the left-hand side of an assignment is uninitialized, it captures the returned value and obtains the correct ownership flag. If the left-hand side *is* initialized, it is automatically destroyed first. Assignment from within Fortran is like pointer assignment. The left-hand side becomes a non-owning reference to the right-hand side. Destruction ----------- Unlike native allocatable Fortran types, Flibcpp derived types are not automatically deallocated when ending a procedure. Therefore to avoid leaking memory, these derived type values must be explicitly cleaned up and released. This is done by the type-bound subroutine named ``release``:: type(Vector), intent(inout) :: v call v%release() If the value ``v`` above owns the associated memory (i.e. if it was constructed in user code), then Flibcpp cleans up and deallocates the C++ instance, and sets ``v`` to an uninitialized state. If ``v`` merely points to existing C++ data, i.e. if it was assigned to the return result of a C++ accessor, then Flibcpp will simply set ``v`` to an uninitialized state. .. ############################################################################ .. end of doc/conventions.rst .. ############################################################################