views:

71

answers:

3

I always assumed that fortran passed entities "by reference" to a dummy argument. Then I got this answer (the actual argument of the answer was related, but not on this)

The standard never specifies that and, indeed goes quite a lot out of its way to avoid such specification. Although yours is a common misconception, it was not strictly accurate even in most older compilers, particularly with optimization turned on. A strict pass-by-reference would kill many common optimizations.

With recent standards, pass-by-reference is all but disallowed in some cases. The standard doesn't use those words in its normative text, but there are things that would be impractical to implement with pass-by-reference.

When you start getting into things like pointers, the error of assuming that everything is pass-by-reference will start making itself more evident than before. You'll have to drop that misconception or many things wil confuse you.

I think other people have answered the rest of the post adequately. Some also addressed the above point, but I wanted to emphasize it.

See here for attribution.

According to this answer, then, there's nothing in the standard specifying how data are shipped from the caller to the callee. In practical terms, how this should be interpreted in terms of actually working with it (regardless of the practical effects resulting from how compilers implement the standard) in particular when it comes to intent() specification?

Edit: I'd like to clarify my question. What I am trying to understand is how the standard expects you to work when you are performing calls. Given that the actual compiler strategy used to pass entities is undefined by the standard, you cannot in principle (according to the standard) expect that passing an argument to a function will actually behave as a "pass-by-reference", with all its related side-effects, because this behavior is compiler and optimization dependent. I assume therefore the standard imposes you a programming style you have to follow to work regardless of the actual implementation strategy.

+3  A: 

Yes, that's true. Fortran standard doesn't specify the exact evaluation strategy for different INTENT attributes. For example, for a dummy argument with INTENT(OUT) some Fortran compiler can use call-by-reference or call-by-copy-restore evaluation.

But I do not understand why do you really need to know which evaluation strategy is used? What is the reason? I think Fortran do it right. Humans concern is (high-level) argument intent, and computers concern is (low-level) evaluation strategy. "Render unto man the things which are man’s and unto the computer the things which are the computer’s." N. Wiener

I think the standard contains enough information on the usage of different INTENT attributes. Section "5.1.2.7 INTENT attribute" of Final Committee Draft of Fortran 2003 standard (PDF, 5 MB) is a good starting point.

kemiisto
Sorry. My title was misleading. My question is not really on knowing the evaluation strategy (which would take advantage on how the standard is implemented by the compiler), but more on how the whole standard expects you to work when you pass stuff around.
Stefano Borini
related: At page 93, intent(out), it says what happens at invocation (becomes undefined) but it says nothing what happens on the caller side. Where can I find this info ? I just see a note (5.14), not an authoritative statement
Stefano Borini
@Stefano: well, if the standard doesn't specify what happens on the caller side it means that it expects you to write your code without any assumptions in this respect.
kemiisto
@kemiisto : then how do I get info out of a subroutine ?
Stefano Borini
@Stefano: the standard (roughly speaking) specifies that, say, the value of intent(out) dummy arguments are found in the actual arguments after the procedure call returns. It just doesn't specify the exact mechanism how this is implemented, and compilers are free to implement it as they see fit, as long as the requirements of the standard are met.
janneb
@janneb: ok, this means that it "behaves like" a pass-by-reference if you don't look inside the box. I think what I'm not able to grasp is the theoretical subtlety about the difference in practical terms. For me, pass-by-reference is when the following behavior occurs: you pass something to a routine, and if the routine modifies it, the callee sees the difference (ie. no copy of the object is done). python and java behave like this, but the point is more on mutability and immutability of the passed entities, to be fair.
Stefano Borini
Stefano Borini
+1  A: 

I'm not sure I understand your question, but one way of seeing things is that as long as one writes standard-conforming code, one does not need to be concerned with how argument passing is implemented. The compiler makes sure (well, barring compiler bugs, of course) that arguments are passed in a way that conforms to the standard.

Now, if you play tricks e.g. with C interop or such, say by comparing argument addresses you might be able to determine whether the compiler uses pass by reference, copy-in/copy-out or something else in some particular case. But generally speaking, at that point you're outside the scope of the standard and all bets are off.

janneb
+2  A: 

As the others have said, you don't have to know how the compiler works, as long as it works correctly. Fortran >=90 allows you to specify the purpose of an argument: input, output or both, and then the compiler takes care of passing the argument. As long as the compiler is correctly implemented so that both sides (caller and callee) use the same mechanism, why should the programmer care? So the Fortran standard tries not to limit how compiler writers implement their compilers, allowing them to design and optimize as they wish.

In terms of programming style, decide the purpose of your procedure arguments, and declare them with the appropriate intent. Then, for example, if you accidentally try to modify an intent(in) argument in a procedure, the compiler will issue an error message, preventing you from making this mistake. It might even do this before emitting object code, so the actual argument passing mechanism has nothing to do with enforcing this requirement of the language.

C is a lower-level language and the programmer needs to choose between passing by value or by reference for various reasons. But for problems such as scientific programming this is an unnecessary aspect to have to control. It can be essential in embedded or device driver programming.

If there is a reason that you must control of the argument passing mechanism, such as interfacing to another language, Fortran 2003 provides the ISO C Binding (which is already widely implemented). With this you can match the C method of argument passing.

M. S. B.