From b081bc9d0466900d9714b2e6353c30140169a778 Mon Sep 17 00:00:00 2001 From: peter klausler Date: Tue, 10 Jul 2018 10:18:34 -0700 Subject: [PATCH] [flang] Address review comments Original-commit: flang-compiler/f18@9e59b9b79d690e0293c61a889da28cbd42ac5194 Reviewed-on: https://github.com/flang-compiler/f18/pull/117 Tree-same-pre-rewrite: false --- flang/documentation/FortranForCProgrammers.md | 66 +++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/flang/documentation/FortranForCProgrammers.md b/flang/documentation/FortranForCProgrammers.md index 0512376..17bc814 100644 --- a/flang/documentation/FortranForCProgrammers.md +++ b/flang/documentation/FortranForCProgrammers.md @@ -74,7 +74,7 @@ Derived types can be parameterized with integer values that either have to be constant at compilation time ("kind" parameters) or deferred to execution ("len" parameters). -Derived types can inherit ("extend") from one other derived type, no more. +Derived types can inherit ("extend") from at most one other derived type. They can have user-defined destructors (`FINAL` procedures). They can specify default initial values for their components. With some work, one can also specify a general constructor function, @@ -108,7 +108,12 @@ Such variables and derived type components are allocated dynamically. They are automatically deallocated when they go out of scope, much like C++'s `std::vector<>` class template instances are. The array bounds, derived type `LEN` parameters, and even the -type of an allocatable can be deferred to run time. +type of an allocatable can all be deferred to run time. +(If you really want to learn all about modern Fortran, I suggest +that you study everything that can be done with `ALLOCATABLE` data, +and follow up all the references that are made in the documentation +from the description of `ALLOCATABLE` to other topics; it's a feature +that interacts with much of the rest of the language.) I/O --- @@ -150,6 +155,22 @@ their own internal procedures. As is the case with C++ lambda expressions, internal procedures can reference names from their host subprograms. +Modules +------- +Modern Fortran has good support for separate compilation and namespace +management. +The `module` is the basic unit of compilation, although independent +subprograms still exist, of course, as well as the main program. +Modules define types, constants, interfaces, and nested +subprograms. + +Objects from a module are made available for use in another compilation +unit via the `USE` statement, which has options for limiting the objects +that are made available as well as for renaming them. +All references to objects in modules is done with direct names or +aliases that have been added to the local scope, as Fortran has no means +of qualifying references with module names. + Arguments --------- Functions and subroutines have "dummy" arguments that are dynamically @@ -182,6 +203,20 @@ scope. This is the opposite of the assumptions under which a C or C++ compiler must labor when trying to optimize code with pointers. +Overloading +----------- +Fortran supports a form of overloading via its interface feature. +By default, an interface is a means for specifying prototypes for a +set of subroutines and functions. +But when an interface is named, that name becomes a *generic* name +for its specific subprograms, and calls via the generic name are +mapped at compile time to one of the specific subprograms based +on the types, kinds, and ranks of the actual arguments. +A similar feature can be used for generic type-bound procedures. + +This feature can be used to overload the built-in operators and some +I/O statements, too. + Polymorphism ------------ Fortran code can be written to accept data of some derived type or @@ -190,7 +225,8 @@ execution, rather than the usual `TYPE` syntax. This is somewhat similar to the use of `virtual` functions in c++. Fortran's `SELECT TYPE` construct is used to distinguish between -possible specific types dynamically. +possible specific types dynamically, when necessary. It's a +little like C++17's `std::visit()` on a discriminated union. Pointers -------- @@ -219,6 +255,27 @@ much portability. Preprocessing is typically requested by the use of a capitalized filename suffix (e.g., "foo.F90") or a compiler command line option. +"Object Oriented" Programming +----------------------------- +Fortran doesn't have member functions (or subroutines) in the sense +of C++ does, in which a function has immediate access to the members +of a specific instance of a derived type. +But Fortran does have an analog to C++'s `this` via *type-bound +procedures*. +This is a means of binding a particular subprogram name to a derived +type, possibly with aliasing, in such a way that the subprogram can +be called as if it were a component of the type (e.g., `X%F(Y)`) +and receive the object to the left of the `%` as an additional actual argument. +The object is passed as the first argument by default, but that can be +changed; indeed, the same specific subprogram can be used for multiple +type-bound procedures by choosing different dummy arguments to serve as +the passed object. +The equivalent of a `static` member function is also available by saying +that no argument is to be associated with the object via `NOPASS`. +There's a lot more that can be said about type-bound procedures (e.g., how they +support overloading) but this should be enough to get you started with +the most common usage. + Pitfalls -------- Variable initializers, e.g. `INTEGER :: J=123`, are _static_ initializers! @@ -230,7 +287,7 @@ that will apply to every fresh instance of the variable. If you see an assignment to an array that's never been declared as such, it's probably a definition of a "statement function", which is like -a parameterized macro definition, e.g. "A(X)=SQRT(X)**3". +a parameterized macro definition, e.g. `A(X)=SQRT(X)**3`. In the original Fortran language, this was the only means for user function definitions. Today, of course, one should use an external or internal function instead. @@ -253,4 +310,3 @@ In fact, Fortran can remove function calls from expressions if their values are not required to determine the value of the expression's result; e.g., if there is a `PRINT` statement in function `F`, it may or may not be executed by the assignment statement `X=0*F()`. - -- 2.7.4