2

I am trying to run some old fortran f77 codes. During compilation I get the following errors. I am using gfortran on a 64-bit Ubuntu 14.04 system.

unsteadyf4.f:300.71:

 3      IHOL(13)/'8'/, IHOL(14)/'9'/, IHOL(15)/' '/, IHOL(16)/','/, 
                                                                   1
Error: Incompatible types in DATA statement at (1); attempted conversion of CHARACTER(1) to INTEGER(4) 
unsteadyf4.f:300.56:

 3      IHOL(13)/'8'/, IHOL(14)/'9'/, IHOL(15)/' '/, IHOL(16)/','/, 
                                                    1
Error: Incompatible types in DATA statement at (1); attempted conversion of CHARACTER(1) to INTEGER(4)
unsteadyf4.f:300.41:

 3      IHOL(13)/'8'/, IHOL(14)/'9'/, IHOL(15)/' '/, IHOL(16)/','/, 
                                     1
Error: Incompatible types in DATA statement at (1); attempted conversion of CHARACTER(1) to INTEGER(4)
unsteadyf4.f:300.26:

 3      IHOL(13)/'8'/, IHOL(14)/'9'/, IHOL(15)/' '/, IHOL(16)/','/, 
                      1
Error: Incompatible types in DATA statement at (1); attempted conversion of CHARACTER(1) to INTEGER(4)
unsteadyf4.f:299.71:

 2      IHOL( 9)/'4'/, IHOL(10)/'5'/, IHOL(11)/'6'/, IHOL(12)/'7'/, 
                                                                   1
Error: Incompatible types in DATA statement at (1); attempted conversion of CHARACTER(1) to INTEGER(4)
unsteadyf4.f:299.56:

 2      IHOL( 9)/'4'/, IHOL(10)/'5'/, IHOL(11)/'6'/, IHOL(12)/'7'/, 
                                                    1
Error: Incompatible types in DATA statement at (1); attempted conversion of CHARACTER(1) to INTEGER(4)
unsteadyf4.f:299.41:

 2      IHOL( 9)/'4'/, IHOL(10)/'5'/, IHOL(11)/'6'/, IHOL(12)/'7'/, 
                                     1
Error: Incompatible types in DATA statement at (1); attempted conversion of CHARACTER(1) to INTEGER(4)
unsteadyf4.f:299.26:

 2      IHOL( 9)/'4'/, IHOL(10)/'5'/, IHOL(11)/'6'/, IHOL(12)/'7'/, 
                      1
Error: Incompatible types in DATA statement at (1); attempted conversion of CHARACTER(1) to INTEGER(4)
unsteadyf4.f:298.70:

 1      IHOL(5)/'0'/, IHOL( 6)/'1'/, IHOL( 7)/'2'/, IHOL( 8)/'3'/,  
                                                                  1
Error: Incompatible types in DATA statement at (1); attempted conversion of CHARACTER(1) to INTEGER(4)
unsteadyf4.f:298.55:

 1      IHOL(5)/'0'/, IHOL( 6)/'1'/, IHOL( 7)/'2'/, IHOL( 8)/'3'/,  
                                                   1
Error: Incompatible types in DATA statement at (1); attempted conversion of CHARACTER(1) to INTEGER(4)
unsteadyf4.f:298.40:

 1      IHOL(5)/'0'/, IHOL( 6)/'1'/, IHOL( 7)/'2'/, IHOL( 8)/'3'/,  
                                    1
Error: Incompatible types in DATA statement at (1); attempted conversion of CHARACTER(1) to INTEGER(4)
unsteadyf4.f:298.25:

 1      IHOL(5)/'0'/, IHOL( 6)/'1'/, IHOL( 7)/'2'/, IHOL( 8)/'3'/,  
                     1
Error: Incompatible types in DATA statement at (1); attempted conversion of CHARACTER(1) to INTEGER(4)
unsteadyf4.f:297.71:

  DATA  IHOL( 1)/'+'/, IHOL( 2)/'-'/, IHOL( 3)/'.'/, IHOL( 4)/'E'/, 
                                                                   1
Error: Incompatible types in DATA statement at (1); attempted conversion of CHARACTER(1) to INTEGER(4)
unsteadyf4.f:297.56:

  DATA  IHOL( 1)/'+'/, IHOL( 2)/'-'/, IHOL( 3)/'.'/, IHOL( 4)/'E'/, 
                                                    1
Error: Incompatible types in DATA statement at (1); attempted conversion of CHARACTER(1) to INTEGER(4)
unsteadyf4.f:297.41:

  DATA  IHOL( 1)/'+'/, IHOL( 2)/'-'/, IHOL( 3)/'.'/, IHOL( 4)/'E'/, 
                                     1
Error: Incompatible types in DATA statement at (1); attempted conversion of CHARACTER(1) to INTEGER(4)
unsteadyf4.f:297.26:

  DATA  IHOL( 1)/'+'/, IHOL( 2)/'-'/, IHOL( 3)/'.'/, IHOL( 4)/'E'/, 
                      1
Error: Incompatible types in DATA statement at (1); attempted conversion of CHARACTER(1) to INTEGER(4)
unsteadyf4.f:297.10:

  DATA  IHOL( 1)/'+'/, IHOL( 2)/'-'/, IHOL( 3)/'.'/, IHOL( 4)/'E'/, 
      1
Error: Incompatible types in DATA statement at (1); attempted conversion of CHARACTER(1) to INTEGER(4)

All the errors are generated from the following part of the code.

    SUBROUTINE INTCOD (IS,NC,ICODE,NERR)
    IMPLICIT DOUBLE PRECISION (A-H,O-Z)
    DIMENSION IS(*),ICODE(*),IHOL(18)
    DATA NSYMB/18/
    DATA  IHOL( 1)/'+'/, IHOL( 2)/'-'/, IHOL( 3)/'.'/, IHOL( 4)/'E'/,
   1      IHOL(5)/'0'/, IHOL( 6)/'1'/, IHOL( 7)/'2'/, IHOL( 8)/'3'/,
   2      IHOL( 9)/'4'/, IHOL(10)/'5'/, IHOL(11)/'6'/, IHOL(12)/'7'/,
   3      IHOL(13)/'8'/, IHOL(14)/'9'/, IHOL(15)/' '/, IHOL(16)/','/,
   4      IHOL(17)/'('/
    NERR = NERR
    DO 200 I=1,NC
    DO 100 J=1,NSYMB
    IF (IS(I) .NE. IHOL(J)) GO TO 100
    ICODE(I)=J
    GO TO 200
100 CONTINUE
    ICODE(I) = 99

I searched for similar errors, link-1 and link-2 and edited the line DIMENSION IS(*),ICODE(*),IHOL(18) as DIMENSION IS(*),ICODE(*),4HIHOL(18).

Now I get the following errors,

unsteadyf4.f:295.32:
    DIMENSION IS(*),ICODE(*),4HIHOL(18)                               
                            1
Error: Invalid character in name at (1)
unsteadyf4.f:297.16:
    DATA  IHOL( 1)/'+'/, IHOL( 2)/'-'/, IHOL( 3)/'.'/, IHOL( 4)/'E'/, 
            1
Error: Syntax error in DATA statement at (1)
unsteadyf4.f:306.6:

    ICODE(I)=J                                                        
    1
Error: Unclassifiable statement at (1)
unsteadyf4.f:309.6:

    ICODE(I) = 99                                                     
    1
Error: Unclassifiable statement at (1)

Sorry for the long post, I knew the minimal reproductive example, but the code is very large and it is hard to simplify.

Any help would be appreciated.

  • If you want `ihol` to be character, you need to declare as character. – francescalus Jan 10 '22 at 08:12
  • Please show more code in your excerpts. We need to see the too of the current subroutine or function or whatever it is. Is there some `IMPLICIT` statement used there? Show it! It is really important. – Vladimir F Героям слава Jan 10 '22 at 08:34
  • @francescalus, I declared `IHOL` and `IS` as characters like this `CHARACTER IS, IHOL*18` and I get only one error now which is `DATA IHOL( 1)/'+'/, IHOL( 2)/'-'/, IHOL( 3)/'.'/, IHOL( 4)/'E'/,` `Error: Syntax error in DATA statement at (1)` – Mohammed Niyasdeen Jan 10 '22 at 09:54
  • @VladimirF, please check the edited code in the main post. – Mohammed Niyasdeen Jan 10 '22 at 09:57
  • 1
    `character ihol*18` declares `ihol` as a scalar character of length 18, which is incompatible with the data statement you have (requiring an 18-long array of length-1 characters). Try either `character ihol(18)` or changing the data statement. See [this other question](https://stackoverflow.com/q/66531967/3157076) for detail on character declarations. – francescalus Jan 10 '22 at 09:59
  • @francescalus, `character ihol(18)` solved the errors and created an executable with some warnings which I am looking into it now. After reading many such errors, I have a question. Since my code is in non-standard form that gfortran-4.8 (my current compiler version) does not support. As per this [link](https://stackoverflow.com/questions/51733778/error-operands-of-logical-operator-eq-at-1-are-integer4-hollerith), do you think changing compilers (Intel(17.0.4) and gfortran (7.3.0)) would be good ? – Mohammed Niyasdeen Jan 10 '22 at 10:31
  • Wait, and what did you do to `IS`? You cannot just compare integer to a character. And you cannot just pass a character into an integer and vice versa. – Vladimir F Героям слава Jan 10 '22 at 10:33
  • @VladimirF, Thats a good questions. I declared like this `CHARACTER IS, IHOL(18)` – Mohammed Niyasdeen Jan 10 '22 at 10:39
  • If you are changing the code to remove non-standard parts you will need to evaluate the _whole code_, not just bits with compiler errors or warnings. The only "safe" compiler to use without changing the code is exactly that for which the non-standard code was designed. – francescalus Jan 10 '22 at 10:41
  • 1
    You **must** also change the code that calls your subroutine. Otherwise the interfaces won't conform and the code is likely to crash or just run incorrectly. If `IS` is character in this subroutine, it simply cannot be `integer` in the subroutine that calls this one. My suggestion for using conversions was to allow small localized changes that might suit better your level of experience. – Vladimir F Героям слава Jan 10 '22 at 10:46
  • @VladimirF, thank you for your suggestion. I was looking at the other files to find the code that calls this subroutine. But strangely there is no any. So I will look into the complete source code again tomorrow. Thanks ! – Mohammed Niyasdeen Jan 10 '22 at 14:10
  • If the code is not actually used, consider just removing it. Otherwise it just confuses everything. – Vladimir F Героям слава Jan 10 '22 at 14:32

2 Answers2

3

Storing "character" data within an integer variable (and manipulating accordingly) is not valid in Fortran 77 or any later revision. It was, however, a common extension provided by compilers.

To use code like

  integer i
  data i/'a'/

end program

you will need to use a compiler which supports that non-standard form. The compiler you are using does not (at least not with the options you are using).

If you do not change the compiler (or its options), you will need to change your code.

How you change your code depends on the rest of the code. You can change the DATA statement so that integer values are provided to the integer variable (although note that the form DATA IHOL( 1)/iachar('+')/ in Vladimir F's answer is no more allowed by the Fortran standards and perhaps fewer compilers accept that as a non-standard extension), or you can change the variable given character values to be character. It is highly likely that, either way, you will need to change other parts of your code.

Kids: non-standard extensions aren't cool.

francescalus
  • 30,576
  • 16
  • 61
  • 96
  • That data statement was really offered as an illustration in an intermediate step so that it is clear what we are trying to achieve. Otherwise the jump is too big for a beginner when the solution looks completely differently. I put a disclaimer even into the initial revision even if it perhaps wasn't definite enough. – Vladimir F Героям слава Jan 10 '22 at 09:04
1

We cannot see what exactly is done with the data. Now with the edit we at least be reasonably convinced that they are the default integers, like 4-byte in modern compilers (and surely in gfortran in default settings).

But if you need the character data to be stored as an integer value, you must use a conversion, like ichar() or iachar(). It is not allowed to assign a character value into an integer. You may of course also change the datatype to character and get rid of the integers.

You will have to stop writing that you have a Fortran 77 code. Your code is not Fortran 77 but mix of some compiler extensions that are not permitted by Fortran 77 or any later Fortran.

We still do not know what how IS() gets its values and what is the exact purpose. The code sample is way too small. The suggestions below assume that IS() elements get their values in a similar way (or perhaps as Holleriths).


If you go ahead and change IHOL to character it is important to do appropriate to IS() as well!

That may mean making it character as well. But those changes must also be made in the code that calls this subroutine! Otherwise you may make a compilable code, but the code will just crash in weird ways.


The simplest change, in may opinion, is the change that is local and tries to get the code working with minimal changes. That way a beginner programmer might be able to keep the logic intact with the hope that all changes remain small and local. An experienced programmer will be able to keep track of large factorization, but honestly, this is not a task for a beginner who tries to get some code compiled. This is what the local conversion from character to integer offers.

This would be the shortest change but does not work for the reasons explained just after. But I believe it is important to show to a beginner where we are aiming to.

DATA  IHOL( 1)/iachar('+')/, IHOL( 2)/iachar('-')/, IHOL( 3)/iachar('.')/, IHOL( 4)/iachar('E')/,

but the requirements for the DATA statement are more strict so these function expressions are not allowed in the DATA statements.

You could use an array constructor instead. It is a Fortran 90 or 2003 feature, but that does not matter in 2022.

INTEGER, DIMENSION(18) :: IHOL = iachar(['+','-','.','E',  ... ])

You might need a different integer kind, that is 1-byte long. Or not, we do not know from your code sample that is too short. Or if the INTEGER*1 syntax is used in your code, you might, as a quick fix, use it here as well.

There might as well be a way how to use a string for the initialization, e.g. in an implied do.

INTEGER I
CHARACTER :: CHOL = "+-.E012...
INTEGER, DIMENSION(18) :: IHOL = [(iachar(CHOL(i:i), i = 1:18)]

Or perhaps the value could be set at runtime. We really do not see enough context, the code you show is too incomplete.


Certainly do not rename IHOL to 4HIHOL, that is both illegal and pointless. Before trying something from some answer, always try to understand what it does. These Hollerith constants are used in expressions instead of a string, so they appear on the right hand side of the assigments. 4HIHOL is used to assign the characters "IHOL" into some integer.

While Holleriths might also be possible quick fixes to similar problems, they are used to assign a string into a single integer, not individual characters to an integer array. And they are not part of the Fortran standard (any more) and the compiler would complain at least in a warning.