Trying To COnvert inherited code to F90

  • Thread starter Thread starter mzottola
  • Start date Start date
  • Tags Tags
    Code Convert
Click For Summary

Discussion Overview

The discussion revolves around a user's attempt to convert least squares code into FORTRAN90, specifically addressing issues related to passing allocatable arrays between a main program and a subroutine. The focus is on debugging segmentation faults that occur during array allocation in the subroutine.

Discussion Character

  • Technical explanation
  • Debate/contested

Main Points Raised

  • The original poster (OP) describes encountering segmentation faults when allocating arrays in a subroutine, despite the code appearing correct.
  • Some participants suggest that the variable N must be declared with the same type in both the main program and the subroutine to avoid alignment issues.
  • Others emphasize that Fortran passes variables by reference, which could lead to memory issues if types do not match.
  • Concerns are raised about the lack of compile-time errors or warnings regarding the undeclared variable N in the main program, despite the use of IMPLICIT NONE.
  • There is a discussion about the historical flexibility of Fortran and how modern compilers may enforce stricter type checking through interfaces.
  • Some participants express skepticism about the OP's understanding of the problem, suggesting that the issue may lie elsewhere in the code.
  • There are comments on the evolution of memory management in programming, particularly regarding constants and their treatment in modern systems.

Areas of Agreement / Disagreement

Participants generally agree that variable type consistency between the main program and subroutine is crucial, but there is no consensus on the exact cause of the segmentation faults. Multiple competing views on the nature of the problem and the handling of variables in Fortran remain unresolved.

Contextual Notes

There are limitations in the provided code snippets, as not all relevant code is shown, which may obscure the root cause of the issue. The discussion also highlights the potential for subtle bugs that may not be immediately apparent from the code shared.

mzottola
Messages
6
Reaction score
0
I have least squares code which I am trying to rewrite in FORTRAN90.
I have a pair of allocatable arrays declared in MAIN. I pass those unallocated
arrays to a subroutine where the arrays are allocated and data is assigned.
However, I get segmentation faults every time I try to run this section of code.

The salient pieces of code are:
(from MAIN)
IMPLICIT NONE
REAL, ALLOCATABLE, DIMENSION(:) :: X,Y
...
CALL GETDATA(X,Y,N)
...
SUBROUTINE GETDATA(X,Y,N)
REAL, ALLOCATABLE, DIMENSION(:) :: X,Y
...(read in values from file - this works)
ALLOCATE(X(N), Y(N))
!N has been determined earlier - and the value is correct.

When I hit the allocate statement, the program dies. This code should work and I am unsure why it is not. If I do this in main I have no problem. But I do not understand why passing values via a subroutine causes problems.

Any ideas why this code may not work would be appreciated.

THanks!
 
Technology news on Phys.org
You use IMPLICIT NONE so, presumably, N is declared somewhere - and also in the subroutine?
I don't know the more 'recent' versions of Fortran but I do know it does not look after you with arrays and data types like the more modern languages.
Sorry if that is too trivial an answer but I don't know your level of familiarity with Fortran.
 
Sophie,

I do declare N as an integer in the subroutines. Since I can use subroutines to communicate with MAIN I did not think it necessary to declare it in the MAIN. I would say I have a reasonable experience base with FORTRAN90, though I do not consider myself a world-class developer, just a competent coder.

If you have further remarks, please do drop them. Since the problem occurs in the subroutine, I am not sure declaring N in the MAIN will have any effect.
 
mzottola said:
Sophie,

I do declare N as an integer in the subroutines. Since I can use subroutines to communicate with MAIN I did not think it necessary to declare it in the MAIN. I would say I have a reasonable experience base with FORTRAN90, though I do not consider myself a world-class developer, just a competent coder.

If you have further remarks, please do drop them. Since the problem occurs in the subroutine, I am not sure declaring N in the MAIN will have any effect.

Since you pass N to the subroutine from a CALL statement in the Main Program, all of the arguments for the subroutine must be declared the same type in both the Main Program and the subroutine itself. If N is declared as INTEGER in the sub, it must also be declared as N in the Main Program, otherwise the data will not align properly, which might be why you're getting segment faults during execution.
 
SteamKing said:
Since you pass N to the subroutine from a CALL statement in the Main Program, all of the arguments for the subroutine must be declared the same type in both the Main Program and the subroutine itself. If N is declared as INTEGER in the sub, it must also be declared as N in the Main Program, otherwise the data will not align properly, which might be why you're getting segment faults during execution.

I remember hearing all sorts of things about how Fortran can let you break the rules. Belt and braces would be my motto.
When Fortran started life, they had very little speed or memory and there was no time to look after the user. You could even change a constant (eg 1) into another (eg 2) on the way through a subroutine.
 
sophiecentaur said:
I remember hearing all sorts of things about how Fortran can let you break the rules. Belt and braces would be my motto.
When Fortran started life, they had very little speed or memory and there was no time to look after the user. You could even change a constant (eg 1) into another (eg 2) on the way through a subroutine.

Whatever. That may have been then, but we are dealing with the here and now.

The variables passed by the Fortran main program to the subroutine and back again are passed by reference, not by value, as in other languages. If the variables in the subroutine definition don't match up with the variables in the CALL statement, then the program may stray into a portion of the memory where it doesn't belong.

All the OP has to do is make sure his variable type declaration statements in the main program and the subroutines match up. This shouldn't be an insurmountable task.
 
I'm surprised the OP didn't get a compile error, or at least a warning that N was not declared in main, given the IMPLICIT NONE statement.

In gfortran, trying to compile
Code:
program mainprog
implicit none
real x,y
call sub(x,y,n)
end
gave me the error I expect to see:
Code:
call sub(x,y,n)
              1
Error: Symbol 'n' at (1) has no IMPLICIT type
 
SteamKing said:
Whatever. That may have been then, but we are dealing with the here and now.

The variables passed by the Fortran main program to the subroutine and back again are passed by reference, not by value, as in other languages.
Which is precisely how the constant 1 can become changed into a 2. The system was efficient in its use of memory, using that method but it could easily allow the overlaying of two different data types on the same memory location. A constant, written in the code is / was treated as a variable, called 1, with value 1 and it could be read or written to as if it were any other data type. That could not happen if the Implicit None statement were used.

If there was not a compile error reported then it seems the same thing can still happen. I am surprised, though. Perhaps the actual problem is not in the code we have been shown and there is something more subtle at work. It wouldn't be the first time.
 
The irony of showing partial code is that it is already filtered out by the OPs perception of where the problem is...which is a bad idea as, clearly, the OP does not know exactly where the problem is; otherwise, s/he wouldn't be asking for help.

Please show the entire source code and enclose it with CODE tags (first "go advance" and then click on the icon with the # symbol, then paste the code in between tags).
 
  • #10
sophiecentaur said:
Which is precisely how the constant 1 can become changed into a 2.
Unless the OP is using an ancient computer or compiler, that is history. These days constants are stored in read-only memory, so you can't overwrite them (but you can crash your program if you try).

That could not happen if the Implicit None statement were used.
Implicit None didn't prevent overwriting constants.

FWIW in Fortran 90 you can declare "interfaces" to functions and subroutines, so that the compiler can do full type checking on the arguments. You can explicitly declare that arguments are for input, output, or both, which generate compile-time errors if you break your own rules.
 
  • #11
AlephZero said:
Unless the OP is using an ancient computer or compiler, that is history. These days constants are stored in read-only memory, so you can't overwrite them (but you can crash your program if you try).


Implicit None didn't prevent overwriting constants.

FWIW in Fortran 90 you can declare "interfaces" to functions and subroutines, so that the compiler can do full type checking on the arguments. You can explicitly declare that arguments are for input, output, or both, which generate compile-time errors if you break your own rules.

DO you really mean ROM? How would that work? - you would need to store a lot of them! But you probably mean something else.

Yes, I totally agree. I was just showing how wide open Fortran used to be. I wonder why anyone would want to be working in Fortran these days - except for legacy stuff.
 
  • #12
sophiecentaur said:
DO you really mean ROM?

Modern computer operating systems have the capability of enforcing that areas of memory are read-only to a particular program. When you compile and link the program, the linker creates several "segments" containing different types of data with different access options. When you load and run the program, the OS sets up the "read-only" data in RAM and then denies the program the option to write to it.

Apart from killing a few old Fortran bugs, this is also useful as a security measure. Malware is also interested in overwriting bits of your program if it gets the opportunity.
 
  • #13
Are you reading the data into X and Y or into another storage space? Are X and Y allocated before the data is stored into them?
 
  • #14
It look like the allocate in the subroutine requires a SAVE attribute if you want X and Y to remain valid when the program leaves the subroutine.
 
  • #15
I seem to remember COMMON and EQUIVALENCE commands, too.
 

Similar threads

  • · Replies 20 ·
Replies
20
Views
3K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 8 ·
Replies
8
Views
4K
  • · Replies 5 ·
Replies
5
Views
8K
  • · Replies 17 ·
Replies
17
Views
3K
  • · Replies 4 ·
Replies
4
Views
4K
Replies
1
Views
2K
  • · Replies 8 ·
Replies
8
Views
2K
Replies
11
Views
16K
  • · Replies 5 ·
Replies
5
Views
2K