0

As part of an assignment, I've been given (old) code for a FORTRAN program. I only have experience with C++ (and Oberon) and what knowledge I do have of Fortran, I've obtained through various (parts of) tutorials, which aren't always consistent with one another. However, despite my basic knowledge this code hurts my eyes with its lack of elegance or consistency. But even more disturbing: it seems to just be full of programming malpractices.

The particular piece of the code I want to ask about looks similar to this example:

PROGRAM Foo

  IMPLICIT NONE

  CALL Bar(0.0,-1)

END PROGRAM Foo

SUBROUTINE Bar(t,i)

  DIMENSION(5) :: R = 0.5
  REAL :: s = 0.5

  DO k = 1, 5
     R(k) = k * i
  END DO
  CALL Random(s) ! Random is a well-behaved pseudorandom number generator
                 ! on the interval ]0,1[ implemented elsewhere.
  k = 1 + (s * 5)
  t = R(k)
END SUBROUTINE Bar

I'll explain what I believe the idea is. Random(s) stores a value between 0.0 and 1.0 in s. This means that 1 + (s * 5) will yield a real number between 1 and 5 (some testing of the pRNG shows that its maximum leads to ~5.992 and its minimum to ~1.0016, say). If the left hand side is an integer, automatic type conversion of the right hand side will occur and the mantissa will be chopped off, leaving an integer value on the interval [1,5]. But k isn't declared as an INTEGER anywhere. Instead, k has been initialized as the loop counter for the DO-loop. Of course this means it must be an integer, but I would think this is bad practice. Am I right? Additionally, I would frown upon the declaration of the array R, since there is no explicit type specifier. I've made it clear that it will store REALs by initializing the array, but this is not done in the actual code...

Of course I've adjusted the actual code more than just that initialization, hopefully adhering to a higher standard. (Imagine IMPLICIT variables, inconsistent capitalization and goto's all over the place.) Also, perhaps I can ask this as well while I'm at it: is the modern standard to end programs, subroutines and functions with the syntax END <PROGRAM/SUBROUTINE/FUNCTION> Name? In the code I was given they simply used END. I've been assuming the correct modern syntax is the one I mentioned, but I'm not sure. Just like I'm not sure if names of programs etc. should be uncapitalized. (in the code I was given they are in all-caps)

Wouter
  • 161
  • 1
  • 6
  • 3
    one other issue here the `Bar=` assignment is illegal in a `subroutine`. Something tells me the original code is not near as inelegant as it is now that you "fixed" it.. – agentp May 16 '14 at 20:43
  • @george Oops, sorry about that. In the actual code, `Bar` is a `subroutine` containing only a call to, say `Bar2`, which is a `function`. I should have paid closer attention when converting the whole to a single `subroutine`. Same thing with the `r` and `R`, I originally named `r` `s` but changed it for some reason. I'll fix those mistakes. It's pretty uncool to assume that I'm just ignorant though, as your second sentence seems to suggest. – Wouter May 16 '14 at 23:24
  • Not sure if you are aware that Fortran is case agnostic. R and r refer to the same variable. – cup May 17 '14 at 06:01
  • @cup I was not, but francescalus mentioned that in v1 of his answer. He took it out after I updated the question to v2. Thanks for the help anyway! – Wouter May 17 '14 at 09:22
  • sorry if you think that too harsh. Naming end statements is not only not required but it was not legal syntax back in the day. Implicit typing is very common in old code, we are all well aware of the issues. The only thing i would *maybe* flag as questionable practice is the implicit `real->int` conversion. I'd likely have done an explicit `int()` call just to make the point that it is deliberate. – agentp May 17 '14 at 13:07
  • @george Well I'd consider the whole to be bad practice: first the implicit typing and then using implicit conversion. This makes things far less transparent and doesn't add to the readability either. Same thing with the `goto`'s and the inconsistent capitalization (which is an aesthetic thing, granted, but important nonetheless). – Wouter May 17 '14 at 16:09
  • Also, it shouldn't matter whether s.th. used to be common practice, programming isn't democratic like that. And I don't know who you mean by "we", but I hope you don't think I was trying to slur people who use(d) implicit typing. That was not my intent. I was only trying to determine if my gut feeling was correct. I didn't know old code often has a lot of implicit typing, and I didn't know naming end statements wasn't allowed in the past. That's *why I asked those questions*. – Wouter May 17 '14 at 16:15

1 Answers1

2

You are largely correct in what you write, but there are some things worth noting.

R and k (and t and i) are victims of implicit typing but it should be noted that it isn't in any way because of how they are used or initialized. Specifically, R would be a real regardless of the =0.5.

Further, before Fortran 95 the loop variable needn't have been an integer. Something like do a=1,5 doesn't force an implicitly typed a to be an integer (but would be incorrect Fortran 95+).

You are certainly correct that modern taste is to have implicit none in every scoping unit - forcing everything to be explicitly typed.

I would, however, take exception to "correct modern syntax": there's nothing incorrect about ending subprograms with just END, but I do prefer and use the longer forms.

Two more minor things to note: explicit initialization implies the save attribute (which has no real effect in this example); Random isn't a standard intrinsic, and if it cannot return 0 then it behaves differently from the standard random_number.

Community
  • 1
  • 1
francescalus
  • 30,576
  • 16
  • 61
  • 96
  • Thanks for your answer. I already commented on the `R` and `r` issue in the comments below the question, but you are indeed correct: that was an artefact of my edit of the original code. I suspected the simple `END` was not incorrect, but my instincts did tell me to go with the longer forms. I'll have to look into that `save` attribute, but I should state that `Random` is indeed a shortcut I used to avoid having to type out the whole implementation. Basically it's a combined linear congruential generator, but the details weren't important for my question so I just put it in there as `Random`. – Wouter May 16 '14 at 23:35
  • Separate `end` cannot be used in internal subprograms until Fortran 2008. Intel Fortran is among the compilers that doesn't allow it there yet. – Vladimir F Героям слава May 17 '14 at 08:31