|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
CompuPayMike
Joined: 10 Mar 2009 Posts: 23 Location: USA
|
Posted: Wed Apr 21, 2010 2:16 pm Post subject: Transfer function |
|
|
I am converting an FTN77 program to FTN95. The old program has a number of places where characters are assigned to integer values.
When I try to compile these subroutines, I get a statement saying that to solve the error I should use the transfer function. I have tried the function, but it also generated an error saying that I cannot change a character array into a scaler value.
Can you provide an example of using this function.
Thank you.
Michael |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Thu Apr 22, 2010 1:21 am Post subject: |
|
|
You could use the intrinsic functions CHAR and ICHAR.
Depending on the packing style of the pre f77 program, there may be more than 1 character to an integer array.
Reading and writing to an integer*2 array with A1 and A2 formats was commonly used and I think still is permitted. I'm surprised that you can not still do that, although it is a much better solution to use character variables and arrays for character data, as they have more implied attributes.
The example below uses an integer*1 array to store the character data, but you could also use an I*2 or I*4 array, with less packing density. I've also tested using A2 to store characters into an I*2 array, using a read statement. It still works! but I would not recommend the approach.
The problem with old style ftn programs is that they tended to mix both integer and character in the same arrays. Fortran 90+ now provides TYPE structures to define mixed data in an array structure.
Code: | integer*4 ic, n, i, i1, i2
integer*2 ib(10)
integer*1 i_char(20)
character cc*20, bb*20, c
!
cc = 'abcdefghijklmnopqrst'
!
n = len (cc)
do i = 1, n
ic = ichar (cc(i:i))
i_char(i) = ic
write (*,1001) i, cc(i:i), ic, i_char(i)
end do
1001 format (i4,a4,2i5)
!
bb = ' '
do i = 1,n
bb(i:i) = char (i_char(i))
end do
write (*,*) cc
write (*,*) bb
!
read (bb,'(10a2)') ib
do i = 1,10
i1 = mod(ib(i),256)
i2 = ib(i) / 256
write (*,'(i4,i6,2a2)') i, ib(i), char(i1), char(i2)
end do
!
end |
|
|
Back to top |
|
|
CompuPayMike
Joined: 10 Mar 2009 Posts: 23 Location: USA
|
Posted: Thu Apr 22, 2010 1:34 pm Post subject: Transfer function |
|
|
My problem is that in a lot of cases the integer values are stored in a common. So I would have to go hunt down all the locations to see how the variable is used. In some cases I think they are used as characters, but in other cases I believe that the integer is actually used.
The asignments are things like this.
Integer*4 A
A = 'abcd'
I am trying to create portable code by compiling in FTN95 with the /ISO option. This way was we move forward if the corporate level decides they want to try different compilers I will not have to worrry about having to rewrite much code.
Thanks.
Michael |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Fri Apr 23, 2010 3:38 am Post subject: |
|
|
I think your problem is that the program you have is not ISO compliant.
Mixing characters in integer variables is pre F77 and I have removed this use out of most programs I have. It stays in some very old 1970's programs that I don't use frequently enough to bother.
You are right in saying that "I would have to go hunt down all the locations to see how the variable is used". You will have to do this !!
The best solution is to locate how these character values are used and then replace the variable with a new character variable.
Usually the character value is in part of the integer array in common and is consistently used as character. If the programmer has mixed the values as integer and character, it is more difficult, but then the extent for which they are character or integer should be for that part of the calculation that they relate.
Back in 70's the mixing of real, integer and character in the same array was to save on storage and in some cases with the final size of the required array not known (not defined explicitly in common in this case). In this case, you need a multiple pass of the data to define the problem size then use separate arrays for integer, real and character. A lot of these techniques were based on sharing memory, which is not necessary today. ALLOCATE is a more elegant solution, once the problem size is known.
The answer you don't want, and that I recommend, is go through all uses of this variable/array in your program and replace the character usage with a character variable.
A good editer/IDE can quickly find this. Even the DOS command: find /i/n "variable" *.f95 > variable.tce : will quickly find what you need. (assuming variables don't continue over column 72!)
Also all common block definitions should be in include files (using /implicit_none).
If the COMMON definition is different in different routines, then the previous programmer has left you a challenge !!
My preferred solution is to try and replace the common by modules and replace the mixed arrays by TYPE structures, although as I've found recently some old techniques, such as use of EQUIVALENCE are difficult to emulate.
On the other hand, what you have should work, with appropriate compiler options, as it did before. But that means it will be difficult to develop this program further to make it look more like a modern program.
All you need is a quite room, away from distractions and a bit of time. Selective global replace can do a lot very quickly.
Good Luck |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|