fortran overload assignment operator

Tutorial OOP(III): Constructors and Destructors

Casting Keynotes: The Virtual Lab

Nov 02 2019

Tutorial OOP(IV) : Operator and Assignment Overloading

  • Filed under blog

In the previous tutorial , we created a constructor and destructor for our TTimer class.  Next, we extend our class with overloaded operators. Depending on the type of object your class represents, you may want to define an addition/subtraction/multiplication/… operator. In addition, the assignment operator deserves some extra attention as you may want to have a clear control over this operation  ( e.g. ,  deep copy vs shallow copy ). The full source of this tutorial and the previous, can be downloaded from my github-page .

Let us start with the latter: the assignment operator . As with all other operators, it is possible to overload the assignment operator in modern fortran.

1. Assignment (=) operator overloading

When dealing with objects and classes—or extended data-structures in general—, their properties often are (implicit) pointers to the actual data-structure. This brings an interesting source of possible bugs due to shallow copies being made while deep copies are expected (although the problem may be less pronounced in Fortran than it is in Python).

In a fortran object, the assignment of a pointer component ( i.e., an explicit pointer variable, or a component which is an object itself) happens via a shallow copy (or pointer assignment). In contrast, for an allocatable component , the assignment operation performs by default a deep copy ( i.e. , space is allocated, and values are copied ). Shallow copies are very useful with regard to quickly creating new handles to the same data-structure. However, if you want to make a true copy, which you can modify without changing the original, then a deep copy is what you want. By implementing assignment overloading for your own classes, you have more control over the actual copying process, and you can make sure you are creating deep copies if those are preferred.

The implementation of overloading for the assignment operator is not too complicated. It requires two lines in your class definition:

First, you need to define a class method which performs a copy-operation—which in a fit or original though we decided to call “ copy ” ;-).  As you can see this function is private, so it will not be accessible to the user of your class via a call like :

Secondly, you link this class method via the “ => ” to the assignment-operator .  It is a generic interface , which means the assignment operator could be linked to different functions, of which the relevant one will be determined and used during run-time. This generic is also public  (otherwise you would not be able to use it).

The implementation of the class method follows the standard rules of any class method and could look like

The “this” object which we passed to our class method is the object on the left side of the assignment operator, while the “from” object is the one on the right side. Note that both objects are defined as “class” and not as “type”. Within the body of this method you are in charge of copying the data from the “from”-object to the “this”-object, giving you control over deep/shallow copying.

In practice the overloaded operator is used as:

2. Operator (+,-,*,/,…) overloading

Just as you can overload the assignment operator above, you can also overload all other fortran operators. However, be careful to keep things intuitive.  For example, an addition operation on our TTimer class is strange. What would it mean to add one timer to another? How would you subtract one chronometer from another? In contrast, inside our TTimer class we have a list of TTime objects which can be used to represent a date and time, as-well-as a time interval. [1]   For the remainder of this tutorial, we will assume the TTime class only represents time-intervals. For such a class, it makes sense to be able to add and subtract time intervals.

Let us start with the basic definition of our TTime-class:

The TTime class has a constructor and destructor, implemented as we discussed before. The assignment operator is over-loaded as well. The overloading of the “ + ” and “ – ” operator follows the same setup as for the assignment operator. First, you define a class method where you will implement the addition or subtraction. Second, you link this class method to the operator as a generic. The main difference with overloading the assignment operator is that you need to use the keyword operator instead of assignment , during the second step. The class methods are private, while the generic link is public. The only thing left to do is to implement the class methods. In case of operator overloading, the class methods are functions .

The returned object need to be defined as a type, and the further implementation of the function follows the standard fortran rules. It is important to note that for a function-header like this one, the object to the left of the operator will be the one calling the overloaded operator function, so:

This may not seem this important, as we are adding two objects of the same class, but that is not necessarily always the case. Imagine that you want to overload the multiplication operator, such that you could multiply your time-interval with any possible real value. On paper

but for the compiler in the left product “this” would be a TTime object and “that” would be a real, while in the right product “this” is the real, and “that” is the TTime object. To deal with such a situation, you need to implement two class methods, which in practice only differ in their header:

In the class definition both functions are linked to the operator as

With this in mind, we could also expand our implementation of the “ + ” and “ – ” operator, by adding functionality that allows for the addition and subtraction of reals representing time-intervals. Also here, the left and right versions would need to be implemented.

As you can see, modern object oriented fortran provides you all the tools you need to create powerful classes capable of operator overloading using simple and straightforward implementations.

In our next Tutorial, we’ll look into data-hiding and private/public options in fortran classes.

[1] You could argue that this is not an ideal choice and that it would be better to keep these two concepts ( absolute and relative time) separate through the use of different classes. 

  • Click to share on Facebook (Opens in new window)
  • Click to share on LinkedIn (Opens in new window)
  • Click to share on Twitter (Opens in new window)
  • Click to share on Reddit (Opens in new window)
  • fortran , Object Oriented Programming , scientific programming

' src=

Vanpoucke Danny

Leave a reply cancel reply.

This site uses Akismet to reduce spam. Learn how your comment data is processed .

Recent Posts

  • First-principles investigation of hydrogen-related reactions on (100)–(2×1)∶H diamond surfaces
  • Cover Nature Reviews Physics
  • Materiomics Chronicles: week 13 & 14
  • How to verify the precision of density-functional-theory implementations via reproducible and universal workflows
  • Materiomics Chronicles: week 11 & 12

© 2014-2020 The Delocalized Physicist.

Made with by Graphene Themes .

Fortran Wiki opover

category: code

fortran overload assignment operator

Fortran/language extensions

  • 1 Procedure Overloading
  • 2 Intrinsic functions
  • 3 Derived Data Types
  • 4.1 Assignment
  • 4.2 Intrinsic operators
  • 4.3 New operators

Procedure Overloading [ edit | edit source ]

Like several other languages, Fortran 90 and newer supports the ability to select the appropriate routine from a list of routines based on the arguments passed. This selection is done at compile time and is thus unencumbered by run-time performance penalties. This feature is accessed by use of modules and the interface block.

In the following example, a module is specified which contains an interface function f which can handle arguments of various types.

A program which uses this module now has access to a single interface function f which accepts arguments that are of integer, real, or complex type. The return type of the function is the same as the input type. In this way the routine is much like many of the intrinsic functions defined as part of the Fortran standard. An example program is given below:

Intrinsic functions [ edit | edit source ]

One can extend intrinsic functions. This is similar to overload operators.

{\displaystyle {\sqrt {4}}=2}

Derived Data Types [ edit | edit source ]

Fortran 90 and newer supports the creation of new data types which are composites of existing types. In some ways this is similar to an array, but the components need not be all of the same type and they are referenced by name, not index. Such data types must be declared before variables of that type, and the declaration must be in scope to be used. An example of a simple 2d vector type is given below.

Variables of this type can be declared much like any other variable, including variable characteristics such are pointer or dimension.

Using derived data types , the Fortran language can be extended to represent more diverse types of data than those represented by the primitive types.

Operator Overloading [ edit | edit source ]

Operators can be overloaded so that derived data types support the standard operations, opening the possibility of extending the Fortran language to have new types which behave nearly like the native types.

Assignment [ edit | edit source ]

The assignment operator = can be overloaded. We will demonstrate this by the following example. Here, we define how the assignment of a logical type on the left and an integer on the right should be performed.

Intrinsic operators [ edit | edit source ]

One can overload intrinsic operators, such as +,-,* .

In the following example we will overload the * operator to work as the logical .and. .

New operators [ edit | edit source ]

One can create newly self-created operators.

We demonstrate this by the following example: We create an unary operator .even. <int> which outputs a logical if the given integer is even as well as a binary operator <reals> .cross. <reals> that performs the standard cross product of two real vectors.

fortran overload assignment operator

  • Book:Fortran

Navigation menu

previous episode

Object oriented programming with fortran, next episode, operator overloading.

Overview Teaching: 10 min Exercises: 5 min Questions What is operator overloading? Objectives Overload the ‘+’ operator.

Previously in the Interface Blocks episode, we saw how interfaces can be used to map one procedure name onto different underlying procedures based on the number, order, and type or arguments passed to the procedure. However, these interface blocks can be used with more than just procedures they can also be used for operators already defined in Fortran such as + , - , * , / , == , /= , and also operators such as .gt. , .le. etc.

Lets add a + operator which appends one of our t_vector objects to another creating a new t_vector .

operators.f90

In the main program you can see how the operator is used, exactly as if we were adding two numbers together. Lets try it out.

Here you can see that the two vectors have been combined into numbers_all with the left hand t_vector object added first followed by the right hand t_vector object added second. So the way we have implemented our operator(+) the results are order dependent.

Which side of an operator? Our main program above looks like so: 111 program main 112 use m_vector 113 implicit none 114 type(t_vector) numbers_some,numbers_less,numbers_all 115 type(t_vector_3) location 116 117 numbers_some=t_vector(4) 118 numbers_some%elements(1)=1 119 numbers_some%elements(2)=2 120 numbers_some%elements(3)=3 121 numbers_some%elements(4)=4 122 print*, "numbers_some" 123 call numbers_some%display() 124 125 numbers_less=t_vector(2) 126 numbers_less%elements(1)=5 127 numbers_less%elements(2)=6 128 print*, "numbers_less" 129 call numbers_less%display() 130 131 numbers_all=numbers_some+numbers_less 132 print*, "numbers_all" 133 call numbers_all%display() 134 135 end program Line 131 is numbers_all=numbers_some+numbers_less what would line 133, call numbers_all%display() print out if line 131 where numbers_all=numbers_less+numbers_some instead? t_vector: num_elements= 6 elements= 1.00000000 2.00000000 3.00000000 4.00000000 5.00000000 6.00000000 the same as before, the + operator is commutative, in other words the order doesn’t matter. t_vector: num_elements= 6 elements= 5.00000000 6.00000000 1.00000000 2.00000000 3.00000000 4.00000000 the contents of numbers_less has been added to the new vector first followed by the contents of numbers_some . Solution NO : while it is true that for the mathematical + operator the order doesn’t matter this is not true for in general for operators. The implementation of the operator must be written in a way that it is order independent and that is now how we wrote it in this case. YES : In our case the order does matter as we first copy the data in the object left side, passed first as left , then the object on the right, passed second as right to the function.
Key Points Common Fortran operators can be overloaded to work with your custom derived types.

10 Overloading operators for derived types

This chapter covers:.

  • Overloading operators in a minimal countdown app
  • Validating user input
  • Synchronization on assignment in the tsunami simulator

Almost any app working with real-world data, or any program more complex than a toy model, will use derived types (classes) to handle abstract data. Fortran’s intrinsic operators for arithmetic ( + , - , * , / , ** ) and comparison ( == , /= , >= , ⇐ , > , < ) are available out of the box for intrinsic numeric ( integer , real , complex ) but not for derived types. For example, to keep track of calendar date and time in an app, you’d need to compare, add, and subtract datetime instances (data structures that represent date and time). This is where derived types (Chapter 6) and generic procedures and custom operators (Chapter 7) come together to form a powerful feature of the language: Overloading intrinsic operators for derived types. This will allow you to define what the intrinsic (and custom) operators mean for any derived type, and in a way extend the syntax of the language.

10.1  Happy Birthday! A countdown app

10.1.1  some basic specification, 10.1.2  implementation strategy, 10.2  getting user input and current time, 10.2.1  your first datetime class, 10.2.2  reading user input, 10.2.3  getting current date and time, 10.3  calculating the difference between two times, 10.3.1  modeling a time interval, 10.3.2  overloading the subtraction operator, 10.3.3  time difference algorithm, 10.3.4  the complete program, 10.4  overloading operators in the tsunami simulator, 10.4.1  a refresher on the field class, 10.4.2  implementing the arithmetic for the field class, 10.4.3   syncing parallel images on assignment, 10.5  answer key, 10.5.1  exercise 1: validating user input, 10.7  summary.

fortran overload assignment operator

Fortran 90: Overloaded Operators

Assigning a derived type variable to itself

I would like to know if anyone knows

  • How should we handle the assignment of a derived type variable to itself when the assignment operator for the derived type is overloaded in a subroutine?
  • How is such a situation mentioned in the Fortran Standard?

Such a situation arises when extending stdlib_sorting to support sorting arrays of bitset_large type. The procedure assign_large overloading assignment operator for the bitset_large type is as follows:

and when the same array element is put on both sides of the assignment operator, an error occurs with the message Fortran runtime error: Allocatable argument 'set2' is not allocated . Here, the stdlib is built with gfortran 11.2.0 on Windows 11 and set2 is defined as the variable on the right-hand side of the assignment operator. The error may be due to the deallocation of the component blocks of set2 caused by the intent(out) attribute for set1 since set1 and set2 are the same variable.

I am trying to resolve this problem by removing assign_large and using Fortran’s intrinsic assignment operation.

For more details, please see the issue #726 and pull-requests #723 and #727 .

Using the intrinsic Fortran assignment without overloading should do, as the derived type doesn’t contain any pointer. However the question still holds for cases where overloading is required (whatever the reason why it is required).

a = a with overloading means that the same variable is passed as the two actual argument of the subroutine, in other words the two dummy arguments get aliased. Argument aliasing is normally not authorized: are there some exceptions?

@tomohirodegawa ,

As mentioned at the stdlib issue thread, argument aliasing is something the author is disallowed and it makes the program nonconforming while the processor is not required to detect and report the nonconformance. Nonetheless, in this case, the processor appears rather kind to do so - is that being overruled ?

There are a couple of options you may want to consider with your colleagues working on stdlib , if that suits you:

  • Consider making the specific procedure of the generic interface accessible and invoke it directly:

I was preparing a similar example to @FortranFan one

The component %n is set to 999 before either calling the assignement routine or the overloaded assignement. In the routine it is first set to zero before being set to what it should be. On output we would like the component to be 999

With gfortran 13.1, the argument aliasing results in the component to be zero in both cases. We can check that the arguments are aliased in the routine.

ifx 2023.1 however can sort it out when using the overloaded assignment. And we can see that it makes a copy-in of b before calling the routine:

I don’t know if ifx is going beyond the standard or if the standard requires this behavior.

EDIT: I can even check that with a = b (b being different from a), ifx is doing a copy-in of b before calling the assign routine. It seems that ifx always considers the RHS as an expression that has to be evaluated with a temporary allocation for the result.

Another option is to implement a setter method for the type that allows you to what you seek: shown below is a clone procedure.

This seems like a general aliasing problem involving assignment. What does a compiler do when it sees an expression like a=a with intrinsic assignment. Does it treat it as a noop, or does it make a copy of the RHS and go through the memory copy process?

With a defined assignment, the programmer could test for the alias (e.g. with c_loc() ), and then do a quick return if necessary. Is that what the fortran standard expects programmers to do?

Or a compiler could always make a copy of the RHS before invoking the assignment function, which could basically double (or more) the effort for complicated derived types – that doesn’t seem optimal either.

Is it the programmer’s responsibility to avoid the a=a situation, or is it the programmer’s responsibility to account for the alias when necessary, or should the compiler avoid the alias by making a RHS copy?

I tend to think the latter is the right one (and possibly optimizing by doing nothing in case of a = a ?), as the first two ones look weird. But I don’t really know.

Upon a bit of further thought, my read is you can change the assignment to explicitly reference an expression on the right-hand side to make the program conform:

And then file another report with GCC Bugzilla for that processor.

This might satisfy the principle of least change for stdlib while enhancing that one processor if the support request is worked on promptly.

The only exceptions are when the aliased arguments are not modified. That is, it is allowed to reference the same actual argument through multiple dummy arguments, so long as none of those dummy arguments are modified. Aliases can also occur for module entities and dummy arguments, but I don’t think that applies to this defined assignment situation.

By the time the assign_large( set1, set2 ) subroutine is invoked, the programmer has already effectively told the compiler that set1 and set2 are not aliased. If this subroutine were invoked in the normal way, then the programmer could place parentheses around the actual argument, making it an expression rather than a variable, and the compiler would then make a copy. That would avoid the aliasing problem, but it would be inefficient when, for example, the argument is a complicated derived type with many levels of allocatable arrays. Then the subsequent assignments within the subroutine might be inefficient when a large amount of memory is copied back to the original derived type variable. The VALUE attribute could also be added to the set2 declaration, and that would also force the compiler to make a copy and avoid the alias problem, but it would have the same efficiency problems for complicated derived types. I don’t think making copies is really the right approach to solve this problem.

It seems like the “best” solution is for the standard to be changed so that the a=a special case is required to be identified by the compiler and to treat it as a noop special case for defined assignment.

I think defined assignment is the only place where this alias issue arises. All the other cases I can think of are already under the programmer’s control (or all arguments are unmodified, so aliases are irrelevant); this is the only one that isn’t. Is that correct?

Is it not an option to make the intent of the left-side argument to inout (rather than out ), so that no auto-initialization (or deallocation) will occur? (Possibly, the need for “pure” makes it not suitable?)

If intent(out) is needed, we might use a separate routine, like

(I guess this is related to the topic of “self-assignment guard (or protection)”, and these pages seem to recommend such a guard in the case of C++ (though other languages may be different.)

  • C++ Tutorial => Self-assignment Protection
  • Self assignment check in assignment operator - GeeksforGeeks
  • https://www.learncpp.com/cpp-tutorial/overloading-the-assignment-operator/

There is no aliasing issue with defined assignment. 10.2.1.5 Note 1 helpfully summarizes:

The rules of defined assignment (15.4.3.4.3), procedure references (15.5), subroutine references (15.5.4), and elemental subroutine arguments (15.8.3) ensure that the defined assignment has the same effect as if the evaluation of all operations in x2 and x1 occurs before any portion of x1 is defined. If an elemental assignment is defined by a pure elemental subroutine, the element assignments can be performed simultaneously or in any order.

Actually the standard defines an assignment as:

R1032 assignment-stmt is variable = expr

A possible interpretation is hence that a compiler is required to process th RHS as an expression, i.e. a = a is actually a = (a) . If so, ifx gets it right and this is a bug in gfortran

The standards document ( https://j3-fortran.org/doc/year/23/23-007r1.pdf ) says:

10.2.1.4 Defined assignment statement (page 191) A subroutine defines the defined assignment x_1 = x_2 if …
10.2.1.5 Interpretation of defined assignment statements** (page 192) … NOTE The rules of defined assignment (15.4.3.4.3) , procedure references (15.5), subroutine references (15.5.4), and elemental subroutine arguments (15.9.3) ensure that the defined assignment has the same effect as if the evaluation of all operations in x_2 and x_1 occurs before any portion of x_1 is defined. If an elemental assignment is defined by a pure elemental subroutine, the element assignments can be performed simultaneously or in any order.
15.4.3.4.3 Defined assignments (page 329) If ASSIGNMENT ( = ) is specified in a generic specification, all the procedures in the generic interface shall be subroutines that can be referenced as defined assignments (10.2.1.4, 10.2.1.5). Defined assignment may, as with generic names, apply to more than one subroutine, in which case it is generic in exact analogy to generic procedure names. Each of these subroutines shall have exactly two dummy arguments. The dummy arguments shall be nonoptional dummy data objects. The first argument shall have INTENT (OUT) or INTENT (INOUT) and the second argument shall have the INTENT (IN) or VALUE attribute. Either the second argument shall be an array whose rank differs from that of the first argument, the declared types and kind type parameters of the arguments shall not conform as specified in Table 10.8, or the first argument shall be of derived type. A defined assignment is treated as a reference to the subroutine, with the left-hand side as the first argument and the right-hand side enclosed in parentheses as the second argument. All restrictions and constraints that apply to actual arguments in a reference to the subroutine also apply to the left-hand-side and to the right-hand-side enclosed in parentheses as if they were used as actual arguments. The ASSIGNMENT generic specification specifies that assignment is extended or redefined. (… bold font by me…)

Here, I am wondering:

[Q1] what happens if x_1 (= the first dummy argument corresponding to the left-side of assignment) is a derived type with an allocatable component and has intent(out) ? Does the standard mean that all the information necessary for evaluating the subroutine will be retrieved by the compiler from x_1 before any re-initialization caused by intent(out) ?

(I imagined that intent(out) causes the re-initialization of x_1 (= resetting to its initial state) by the compiler (like deallocation of allocatable components) immediately after entering the subroutine. It seems to be what is happening in various code snippets above, because segmentation fault happens if intent(out) is used. Is my interpretation above not correct…?)

[Q2] Does the section 15.4.3.4.3 (Defined assignments) above mean that

should be interpreted as equivalent to a subroutine call like

That is the way I read the above text. However, in the x1=x1 case, or an equivalent situation, it seems like this could result in a lot of redundant and unnecessary effort. Is a compiler allowed to recognize this situation and treat it as a special case? Should a processor be required to recognize this special case and avoid that unnecessary effort?

Even in the case of x1 /= x2 , if the compiler sends (x2) as a temporary variable (after making a deep copy of x2 ), I guess it would need a lot of unnecessary effort… But maybe as an optimization, ifx possibly examines the address of actual arguments on the caller side and determines which of assign( x1, x2 ) and assign( x1, (x2) ) to use internally…?

Apart from that, my concern is that even when a temporary variable like (a) is created, direct translation of a = a to assign( a, (a) ) might give a wrong result (unless it is converted to “no op”). One such case may be when a is a derived-type variable and has a pointer component that points to another allocatable component in the same type. When entering the assign() routine, a temporary variable of RHS is created (e.g. via bitwise copy), while allocatable components of LHS could be deallocated via intent(out) , so the original pointer can become ill-defined… (something like the following).

(To avoid this kind of trouble, the [Q1] above comes into play…? (like getting the value of right% val first when entering assign() …?)

To me, definitely yes.

Thank you for the information from various perspectives and helpful discussion.

I understand there are four ways to avoid self-assignment a=a using overloaded assignment operations for derived types.

  • Use the intrinsic assignment operation for derived types.
  • Set the intent(inout) attribute to the argument on the left-hand side of the assignment operator and introduce the self-assignment guard (in the context of C++) using c_loc .
  • Set the value attribute to the argument on the right-hand side of the assignment operator.
  • Explicitly refer to the variable on the right-hand side of the assignment operator using () .

I’m currently trying to support the sorting procedures in stdlib to the bitset_large type. 4 requires modifications, verifications, and performance measurements of the sorting procedures, even for already supported types. 1 is considered to be the most realistic way for the bitset_large type because bitset_large type doesn’t have pointer component.

I have zero experience with the bitset type up to now (so cannot imagine what is best for library implementation), but personally in my codes, I stick to intrinsic assignment when a given composite type is planned to have no pointers inside. If some class has a pointer, I explicitly call a custom subroutine, partly because I am still not sure what happens under the hood for defined assignment… (I will ask about this later). Also, if the second argument is internally passed with (...) , it may be meaningless to take its address for self-assignment guard.

One more problem may be that one cannot forbid the inclusion of pointer components into a derived type. So, we may need to make sure that future people will not inadvertently add pointers if intrinsic assignment is used throughout.

:sweat_smile:

And also because the allocatable component has a default lower bound. In the case of an allocatable component with non-default lower bound, the intrinsic assignement would not be able to correctly transfer the bounds to the assigned object.

Related Topics

fortran.cat

A few bits of Fortran

  • English , fortran , language , llenguatge

Operator (+) overload in a class

' data-src=

Overloading a subroutine means to redefine its internal functionality for a customized behavior. Overall it adapts the class new characteristics to already wide-spread Fortran functionalities (==, =, + ,-, …).

Specifically, this post only focus on the operators (+,-,*,/).

In the following example, m ynumber is generic class to hold any type of an integer number. For that reason, it seems interesting enough to be able to directly operate with its data.

The main program shows what is meant to do:

In short, mynumber type can directly operate with:

  • mynumber + mynumber
  • mynumber + scalar int
  • scalar int + mynumber

Therefore, there must be an implementation for each type of operation. Check below how to do it:

For each desired operation, it requires its own implementation. In order to include subtraction, division or multiplication, you only need to apply the same principle but with the following signs: -, *, /.

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Save my name, email, and website in this browser for the next time I comment.

Recent Posts

  • Edge cases when implementing scientific equations
  • Mapping namelists from a derived type
  • How to profile a Fortran binary with the ‘perf’ tool
  • Parametrized derived types (PDT)
  • How to raise an error with a stack trace
  • What is Fortran
  • February 2024
  • November 2023
  • September 2023
  • December 2022
  • February 2022
  • December 2021
  • November 2021
  • October 2021
  • September 2021
  • Performance

Proudly Powered By WordPress

Operator Overloading

  • First Online: 01 January 2011

Cite this chapter

Book cover

  • Ian Chivers 3 &
  • Jane Sleightholme 4  

7281 Accesses

The aims of this chapter are to look at operator overloading in Fortran.

All the persons in this book are real and none is fictitious even in part.

Flann O’Brien, The Hard Life

This is a preview of subscription content, log in via an institution to check access.

Access this chapter

Institutional subscriptions

Author information

Authors and affiliations.

Rhymney Consulting, London, UK

Ian Chivers

Fortranplus, London, UK

Jane Sleightholme

You can also search for this author in PubMed   Google Scholar

Rights and permissions

Reprints and permissions

Copyright information

© 2012 Springer-Verlag London Limited

About this chapter

Chivers, I., Sleightholme, J. (2012). Operator Overloading. In: Introduction to Programming with Fortran. Springer, London. https://doi.org/10.1007/978-0-85729-233-9_23

Download citation

DOI : https://doi.org/10.1007/978-0-85729-233-9_23

Published : 01 November 2011

Publisher Name : Springer, London

Print ISBN : 978-0-85729-232-2

Online ISBN : 978-0-85729-233-9

eBook Packages : Computer Science Computer Science (R0)

Share this chapter

Anyone you share the following link with will be able to read this content:

Sorry, a shareable link is not currently available for this article.

Provided by the Springer Nature SharedIt content-sharing initiative

  • Publish with us

Policies and ethics

  • Find a journal
  • Track your research

Overloading and Generic Programming

Overloading is when a procedure or operator is able to work on multiple types. Most languages overload at least basic arithmetic operators to work on all numerical types. In modern Fortran the mathematical intrinsics are overloaded to work at least on real and double precision, and when appropriate complex. For example, in older Fortran there were three versions of every trigonometric function when defined for complex numbers. Cosine was COS for real number, DCOS for doubles, and CCOS for complex. In modern Fortran COS works for all three. This is an example of generic programming.

Overloading can be more general than just numerical types. In some languages, sort is an intrinsic and works on any types for which relational operators (<,<=,>,>=) are defined.

Programmers can overload their own procedures in Fortran. To make a generic procedure, an interface is required. In this case the interface block has a name, which will be the generic name, and only the specific procedures should be included.

In all the examples below, our new generic diag for computing the diagonal of a matrix, will accept either real or double precision arrays. The extension to complex should be obvious if it is needed.

Explicit Interface Block

We can use an explicit interface block in a non-module program unit.

Module Procedure

Overloaded procedures are usually and most appropriately defined in a module. Since procedures in modules already have an implicit interface, we cannot use the explicit interface above. We still use a named interface block with MODULE PROCEDURE

The body of the functions would be in the module.

Generic in Type-Bound Procedures

If we wanted to define something with various linear-algebra functions defined on it, we would use the GENERIC keyword. Note that the specific functions must be written so that their signatures , the number and types of their arguments, are differ, or the compiler will not be able to distinguish them.

Operator Overloading

The arithmetic operators + , - , * ,and / can be overloaded to work on programmer-defined derived types. Assignment (=) can also be overloaded when copying can be defined for the type.

Module Procedures

The arithmetic operators are overloaded with a generic interface, but rather than the name of the generic function, the keyword OPERATOR is used, followed by the symbol in parentheses for operators, or ASSIGNMENT(=) for copying.

The procedures that define the operator must be functions , must have two arguments, and must declare those arguments INTENT(IN). For example, suppose we wished to define adder for an Atom type to add the atomic masses:

For assignment, the procedure must be a subroutine with two arguments. The first argument must represent the left-hand side and be INTENT(OUT), while the second represents the right-hand side and is INTENT(IN).

Type-Bound Operators

Operators may be overloaded to work on class members. The syntax is somewhat different than for separate types in modules. Here is a snippet from a module defining a Fraction class. The rules for the arguments are the same as for modules, but of course the instance variable must be declared CLASS.

Last updated on Jan 1, 0001

Success! Subscription added.

Success! Subscription removed.

Sorry, you must verify to complete this action. Please click the verification link in your email. You may re-send via your profile .

  • Intel Community
  • Developer Software Forums
  • Software Development Tools
  • Intel® Fortran Compiler

Problem with overloaded assignment when LHS is allocatable array

  • Subscribe to RSS Feed
  • Mark Topic as New
  • Mark Topic as Read
  • Float this Topic for Current User
  • Printer Friendly Page

Vivek_R_

  • Mark as New
  • Report Inappropriate Content

FortranFan

View solution in original post

  • All forum topics
  • Previous topic

Link Copied

IanH

Community support is provided during standard business hours (Monday to Friday 7AM - 5PM PST). Other contact methods are available here .

Intel does not verify all solutions, including but not limited to any file transfers that may appear in this community. Accordingly, Intel disclaims all express and implied warranties, including without limitation, the implied warranties of merchantability, fitness for a particular purpose, and non-infringement, as well as any warranty arising from course of performance, course of dealing, or usage in trade.

For more complete information about compiler optimizations, see our Optimization Notice .

  • ©Intel Corporation
  • Terms of Use
  • *Trademarks
  • Supply Chain Transparency

IMAGES

  1. Fortran Programming Tutorials (Revised) : 017 : Modulus Operation

    fortran overload assignment operator

  2. Assignment operator

    fortran overload assignment operator

  3. Operators in FORTRAN

    fortran overload assignment operator

  4. [Solved] Correctly overload assignment operator for

    fortran overload assignment operator

  5. How to Overload Assignment Operator in C#

    fortran overload assignment operator

  6. Fortran Programming Tutorials (Revised) : 026 : Array operations, Changing Index

    fortran overload assignment operator

VIDEO

  1. Relational Operator Overloading in C++ [Hindi]

  2. Operators in FORTRAN

  3. OR Operator Fortran

  4. AND Operator Fortran

  5. 5. Programming with modern FORTRAN. Variables and assignment operator

  6. OverloadAssignment

COMMENTS

  1. oop

    9. = is not an operator, it is an assignment in Fortran and they are very different beasts. To the classical possibility found in Fortran 90 and explained well in other answers, Fortran 2003 added a better possibility to bind the overloaded operators and assignments with the derived type. This way you are sure you will not import the type ...

  2. Tutorial OOP(IV) : Operator and Assignment Overloading

    Let us start with the latter: the assignment operator. As with all other operators, it is possible to overload the assignment operator in modern fortran. 1. Assignment (=) operator overloading. When dealing with objects and classes—or extended data-structures in general—, their properties often are (implicit) pointers to the actual data ...

  3. opover in Fortran Wiki

    opover in Fortran Wiki. @(#) Example of overloading operators in Fortran ! ! The following MODULE allows for using the syntax ! L1 == L2 ! where L1 and L2 are LOGICAL ! as an alternative to ! L1 .EQV. L2 ! (or the function call ! BOOLEAN_EQUAL (L1, L2)) ! or ! L1 .BOOLEAN_EQUAL. L2 ! for that matter); and likewise allows !

  4. How to overload assignment (=) in a class

    Overloading a subroutine means to redefine its internal functionality for a customized behavior. Overall it adapts the class new characteristics to already wide-spread Fortran functionalities (==, =, + ,-, …). Specifically, this post only focus on assignment (=). In the following example, Mynumber is generic class to hold any type of real number.

  5. Fortran/language extensions

    Operator Overloading [edit | edit source] Operators can be overloaded so that derived data types support the standard operations, opening the possibility of extending the Fortran language to have new types which behave nearly like the native types. Assignment [edit | edit source] The assignment operator = can be overloaded.

  6. Operator Overloading

    What is operator overloading? Objectives. Overload the '+' operator. Previously in the Interface Blocks episode, we saw how interfaces can be used to map one procedure name onto different underlying procedures based on the number, order, and type or arguments passed to the procedure. However, these interface blocks can be used with more ...

  7. PDF Chapter 24 Operator Overloading

    The aims of this chapter are to look at operator overloading in Fortran. 24.1 Introduction In programming operator overloading can be regarded as a way of achieving polymorphism in that operators (e.g. +, −, * , / or =) can have different imple- ... Fortran introduced support for operator and assignment overloading in the 1990 standard. 24.2 ...

  8. Operator Overloading

    In Fortran for example, the addition + operator invokes quite different code when used with integer, real or complex types. Some languages allow the programmer to implement support for user defined types . Fortran introduced support for operator and assignment overloading in the 1990 standard.

  9. 10 Overloading operators for derived types · Modern Fortran: Building

    This is where derived types (Chapter 6) and generic procedures and custom operators (Chapter 7) come together to form a powerful feature of the language: Overloading intrinsic operators for derived types. This will allow you to define what the intrinsic (and custom) operators mean for any derived type, and in a way extend the syntax of the ...

  10. Operator Overloading

    In Fortran for example, the addition + operator invokes quite different code when used with integer, real or complex types. Some languages allow the programmer to implement support for user defined types. Fortran introduced support for operator and assignment overloading in the 1990 standard.

  11. Fortran 90: Overloaded Operators

    Fortran 90: Overloaded Operators Let's start this section out with an example. Define the data type vector, which is a double precision array of length 3. type vector real*8 :: v(3) end type vector ... Once again, operator overloading could be used to call this function with the "*" operator. Or if that may be confusing, we can define a new ...

  12. Operator functions in F90

    Caveat in operator overloading Recall that Fortran has operators on arrays . Make sure that you do not (unintentionally) collide with an existing F90 operator . ... As in C++, Fortran 90 provides a default assignment operator to every user defined type. Example: TYPE(MyType) :: x, y y = x!! Copies each field from x to y

  13. Assigning a derived type variable to itself

    Using the intrinsic Fortran assignment without overloading should do, as the derived type doesn't contain any pointer. However the question still holds for cases where overloading is required (whatever the reason why it is required). a = a with overloading means that the same variable is passed as the two actual argument of the subroutine, in ...

  14. Operator (+) overload in a class

    Overloading a subroutine means to redefine its internal functionality for a customized behavior. Overall it adapts the class new characteristics to already wide-spread Fortran functionalities (==, =, + ,-, …). Specifically, this post only focus on the operators (+,-,*,/). In the following example, m ynumber is generic class to hold any type ...

  15. Operator Overloading

    In Fortran for example, the addition + operator invokes quite different code when used with integer, real or complex types. Some languages allow the programmer to implement support for user defined types. Fortran introduced support for operator and assignment overloading in the 1990 standard. 23.1.1 Other Languages

  16. Overloading and Generic Programming

    Type-Bound Operators. Overloading and Generic Programming. Overloading is when a procedure or operator is able to work on multiple types. Most languages overload at least basic arithmetic operators to work on all numerical types. In modern Fortran the mathematical intrinsics are overloadedto work at least on real and double precision, and when ...

  17. Problem with overloaded assignment when LHS is allocatable array

    In this case, the standard essentially places the onus on the program (and by extension its author) to conform, the processor (compiler being part of it) is not required to issue diagnostics. And the issue is this: with the defined assignment as specified, the standard semantics requires the 'ialloc` to be allocated to the right shape prior to ...

  18. fortran operator overloading: function or subroutine

    interface operator (/) module procedure div_fun end interface allowing. q = f/g ! Could be slower, but looks good. call div_sub2(f,g,q) as we note that to be used as a binary operator (see Fortran 2008 7.1.5, 7.1.6) the procedure must be a function. In response to your comment to a previous revision of this answer

  19. Fortran derived types: Overloaded assignment operator not working with

    My reading of the standard is that one cannot use a defined operator here. My thinking is that this is because the operator is for defined assignment where for a named constant initialization is used (see R503 and C507 of Fortran 2008, in section 5.2.1).. In Fortran 2008 section 5.2.3, regarding initialization: