- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I get a strange error message (at least for me) like:
Error: The type of the actual argument differs from the type of the dummy argument. ['ABCDE']
when I have this code:
! somewhere in the declarations:
Interface
CHARACTER(len=80) FUNCTION MYFUNC(MYVAR,FIELD,FVALUE,
+ MYERR)
END FUNCTION MYFUNC
End interface
CHARACTER*(*) ABCDE ! CHARACTER(len=80) ABCDE makes no difference
! later on:
ABCDE = MYFUNC ('ABCDE', FIELD, FVALUE, MYERR)
! and the function goes like:
CHARACTER(len=80) FUNCTION MYFUNC (MYVAR,FIELD,FVALUE,MYERR)
! some declarations
CHARACTER(len=80) :: MYVAR
CHARACTER(len=80) :: STRING
! something more
MYFUNC = STRING
RETURN
END FUNCTION MYFUNC
IMO all the variables have the correct type, especially ABCDE when being submitted into the function call. Where do I go wrong?
I get a strange error message (at least for me) like:
Error: The type of the actual argument differs from the type of the dummy argument. ['ABCDE']
when I have this code:
! somewhere in the declarations:
Interface
CHARACTER(len=80) FUNCTION MYFUNC(MYVAR,FIELD,FVALUE,
+ MYERR)
END FUNCTION MYFUNC
End interface
CHARACTER*(*) ABCDE ! CHARACTER(len=80) ABCDE makes no difference
! later on:
ABCDE = MYFUNC ('ABCDE', FIELD, FVALUE, MYERR)
! and the function goes like:
CHARACTER(len=80) FUNCTION MYFUNC (MYVAR,FIELD,FVALUE,MYERR)
! some declarations
CHARACTER(len=80) :: MYVAR
CHARACTER(len=80) :: STRING
! something more
MYFUNC = STRING
RETURN
END FUNCTION MYFUNC
IMO all the variables have the correct type, especially ABCDE when being submitted into the function call. Where do I go wrong?
Link Copied
17 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
'ABCDE' is CHARACTER*5, not CHARACTER*80. You probably wanted CHARACTER(*) instead. If you had assigned back into MYVAR, you would have corrupted memory.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
sblionel wrote:
'ABCDE' is CHARACTER*5, not CHARACTER*80. You probably wanted CHARACTER(*) instead. If you had assigned back into MYVAR, you would have corrupted memory.
Unfortunately the compiler complains when I try to define
Interface
CHARACTER(len=*) FUNCTION MYFUNC(...)
END FUNCTION MYFUNC
End interface
and says no asterisk is allowed there. As I want to use MYFUNC not only with CHARACTER*5, which number do I have to take?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That's not what I suggested. The issue is with the argument(s), not the function itself.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sorry for annoying you but I am new to Fortran and I do not get this problem solved - maybe I should go back to Java. =:-|
No matter what I change, I still get the same error. If I change the declaration to CHARACTER*5 :: ABCDE or CHARACTER(len=5) :: ABCDE
What am I doing wrong, what do I misunderstand? :-(
No matter what I change, I still get the same error. If I change the declaration to CHARACTER*5 :: ABCDE or CHARACTER(len=5) :: ABCDE
What am I doing wrong, what do I misunderstand? :-(
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You are passing a five-character value, 'ABCDE', but have declared the argument receiving it, MYVAR, as 80-characters. This is a mismatch.
What you want is something like this:
CHARACTER(len=80) FUNCTION MYFUNC (MYVAR,FIELD,FVALUE,MYERR)
! some declarations
CHARACTER(len=*) :: MYVAR
CHARACTER(len=*) :: STRING
! something more
MYFUNC = STRING
RETURN
END FUNCTION MYFUNC
This tells the compiler to use the length of the value that was passed, rather than a fixed 80.
It is not clear to me how you are using this function. It will always return an 80-character string, blank padded. Is that what you want? The code you showed for declaring variable ABCDE (not the literal 'ABCDE') can't be CHARACTER(*) - it has to have a fixed length.
What you want is something like this:
CHARACTER(len=80) FUNCTION MYFUNC (MYVAR,FIELD,FVALUE,MYERR)
! some declarations
CHARACTER(len=*) :: MYVAR
CHARACTER(len=*) :: STRING
! something more
MYFUNC = STRING
RETURN
END FUNCTION MYFUNC
This tells the compiler to use the length of the value that was passed, rather than a fixed 80.
It is not clear to me how you are using this function. It will always return an 80-character string, blank padded. Is that what you want? The code you showed for declaring variable ABCDE (not the literal 'ABCDE') can't be CHARACTER(*) - it has to have a fixed length.
Message Edited by sblionel on 03-21-2005 11:22 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Of course a fixed return value is not the best solution. But what can be done, when
CHARACTER(len=*) FUNCTION MYFUNC (MYVAR,FIELD,FVALUE,MYERR)
...
is not allowed?
CHARACTER(len=*) FUNCTION MYFUNC (MYVAR,FIELD,FVALUE,MYERR)
...
is not allowed?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What exactly are you trying to accomplish? What does the function do?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The function just looks up some Character/String if it is contained in an array and returns a number which depends to the string in the array. Like looking up a value in a table.
Table e.g.:
1-AERR
2-BBD
3-CHD
4-CDEFG
5-KLABUM
So if CDEFG shall be looked up, the return value as String is "4" and so on. But it is not my task to rewrite this function but to get the original code to work in Intel Frotran Compiler 8.1... :o At the moment I have the choice between two error messages, but of course I have to get rid of them. Unfortunately I don't know how.
Table e.g.:
1-AERR
2-BBD
3-CHD
4-CDEFG
5-KLABUM
So if CDEFG shall be looked up, the return value as String is "4" and so on. But it is not my task to rewrite this function but to get the original code to work in Intel Frotran Compiler 8.1... :o At the moment I have the choice between two error messages, but of course I have to get rid of them. Unfortunately I don't know how.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ok - there are two problems in the code you showed in your original post. The first is that the INTERFACE block does not declare the arguments. The second is that you have character arguments with explicit lengths where they really should be (*). So what you want is something like this:
Interface
CHARACTER(len=80) FUNCTION MYFUNC(MYVAR,FIELD,FVALUE,
+ MYERR)
CHARACTER(len=*) MYVAR, FIELD
INTEGER FVALUE, MYERR ! I didn't know what these really were
END FUNCTION MYFUNC
End interface
then the actual function would have the same declarations.
There isn't really a problem with MYFUNC returning CHARACTER(80). If you knew that the length was always 2 or 1, you could make it CHARACTER(2).
Interface
CHARACTER(len=80) FUNCTION MYFUNC(MYVAR,FIELD,FVALUE,
+ MYERR)
CHARACTER(len=*) MYVAR, FIELD
INTEGER FVALUE, MYERR ! I didn't know what these really were
END FUNCTION MYFUNC
End interface
then the actual function would have the same declarations.
There isn't really a problem with MYFUNC returning CHARACTER(80). If you knew that the length was always 2 or 1, you could make it CHARACTER(2).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Maybe I am stupid, maybe I just do not understand how the variable declarations, parameters and return values work. Maybe I am blind, anyway I still couldn't fiddle out to get this code to work.
Currently I have this:
program CharString
implicit none
CHARACTER(len=80) VAR1
CALL MyFunc(Var1)
end program CharString
SUBROUTINE MyFunc(Var1)
implicit none
CHARACTER*(*) VAR1
CHARACTER(len=*) :: CALLER
! CHARACTER CALLER*(*)
CHARACTER VAL2(*)*(*)
CHARACTER VAL3(*)*(*)
INTEGER VAL4(*)
!------------------------
Interface
CHARACTER(len=80) FUNCTION CHANGE(VAL1,VAL2,VAL3,VAL4)
CHARACTER(len=*) VAL1
INTEGER VAL4(*)
CHARACTER VAL2(*)*(*)
CHARACTER VAL3(*)*(*)
! CHARACTER VAL1(*)*(*)
END FUNCTION CHANGE
End interface
!------------------------
CALLER = CHANGE('CALLER', VAL2, VAL3, VAL4)
END SUBROUTINE
!------------------------
!------------------------
CHARACTER(len=80) FUNCTION CHANGE (VAL1,VAL2,VAL3,VAL4)
INTEGER VAL4(*)
INTEGER COUNTER
CHARACTER VAL2(*)*(*)
CHARACTER VAL3(*)*(*)
! CHARACTER VAL1*(*)
CHARACTER(len=*) :: VAL1
CHARACTER(len=*) :: STRING
COUNTER = 1
DO 55 I = 1, 999
IF (VAL2(COUNTER) .EQ. ' ') GOTO 66
IF (VAL2(COUNTER) .EQ. VAL1) THEN
STRING = VAL3(COUNTER)
CALL CLEFT (STRING)
CHANGE = STRING
VAL4(COUNTER) = 0
GOTO 99
END IF
COUNTER = COUNTER + 1
55 CONTINUE
66 CONTINUE
CHANGE =' '
GOTO 99
77 VAL4(COUNTER) = 77
CHANGE =' '
99 RETURN
END FUNCTION CHANGE
!------------------------
And what I get is first of all (besides several others):
Error: This passed length character name has been used in an invalid context. [CALLER] indicated for line #11 within the subroutine in the declaration part:
CHARACTER(len=*) :: CALLER
In which context and why? And what has to be changed so that it works?
Currently I have this:
program CharString
implicit none
CHARACTER(len=80) VAR1
CALL MyFunc(Var1)
end program CharString
SUBROUTINE MyFunc(Var1)
implicit none
CHARACTER*(*) VAR1
CHARACTER(len=*) :: CALLER
! CHARACTER CALLER*(*)
CHARACTER VAL2(*)*(*)
CHARACTER VAL3(*)*(*)
INTEGER VAL4(*)
!------------------------
Interface
CHARACTER(len=80) FUNCTION CHANGE(VAL1,VAL2,VAL3,VAL4)
CHARACTER(len=*) VAL1
INTEGER VAL4(*)
CHARACTER VAL2(*)*(*)
CHARACTER VAL3(*)*(*)
! CHARACTER VAL1(*)*(*)
END FUNCTION CHANGE
End interface
!------------------------
CALLER = CHANGE('CALLER', VAL2, VAL3, VAL4)
END SUBROUTINE
!------------------------
!------------------------
CHARACTER(len=80) FUNCTION CHANGE (VAL1,VAL2,VAL3,VAL4)
INTEGER VAL4(*)
INTEGER COUNTER
CHARACTER VAL2(*)*(*)
CHARACTER VAL3(*)*(*)
! CHARACTER VAL1*(*)
CHARACTER(len=*) :: VAL1
CHARACTER(len=*) :: STRING
COUNTER = 1
DO 55 I = 1, 999
IF (VAL2(COUNTER) .EQ. ' ') GOTO 66
IF (VAL2(COUNTER) .EQ. VAL1) THEN
STRING = VAL3(COUNTER)
CALL CLEFT (STRING)
CHANGE = STRING
VAL4(COUNTER) = 0
GOTO 99
END IF
COUNTER = COUNTER + 1
55 CONTINUE
66 CONTINUE
CHANGE =' '
GOTO 99
77 VAL4(COUNTER) = 77
CHANGE =' '
99 RETURN
END FUNCTION CHANGE
!------------------------
And what I get is first of all (besides several others):
Error: This passed length character name has been used in an invalid context. [CALLER] indicated for line #11 within the subroutine in the declaration part:
CHARACTER(len=*) :: CALLER
In which context and why? And what has to be changed so that it works?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It would seem that you need to learn a bit more about the Fortran language. I can't really tell what your program wants to do, but I'll make some observations that may be helpful.
When you have a declaration such as:
INTEGER VAL4(*)
that says that VAL4 is an integer array whose lower bound is 1 and whose upper bound is unspecified. An upper bound of * is allowed only inside routines for its formal arguments.
CHARACTER VAL2(*)*(*)
means that VAL2 is an array of character strings. The upper bound of the array is unspecified and the length of each array element (all the same) is passed in by the caller to the routine (this is done by the compiler.) Again, this is valid for arguments only. In MyFunc, CALLER, VAL2, VAL3 and VAL4 are local variables, not arguments, so may not have (*) array bounds or (*) character lengths.
Your declaration of STRING is invalid because (len=*), which is the same as (*) after CHARACTER, is allowed only for arguments.
When you say something like:
STRING = VAL3(COUNTER)
You are assigning to STRING an array element from VAL3.
What did your original code look like before you changed it?
When you have a declaration such as:
INTEGER VAL4(*)
that says that VAL4 is an integer array whose lower bound is 1 and whose upper bound is unspecified. An upper bound of * is allowed only inside routines for its formal arguments.
CHARACTER VAL2(*)*(*)
means that VAL2 is an array of character strings. The upper bound of the array is unspecified and the length of each array element (all the same) is passed in by the caller to the routine (this is done by the compiler.) Again, this is valid for arguments only. In MyFunc, CALLER, VAL2, VAL3 and VAL4 are local variables, not arguments, so may not have (*) array bounds or (*) character lengths.
Your declaration of STRING is invalid because (len=*), which is the same as (*) after CHARACTER, is allowed only for arguments.
When you say something like:
STRING = VAL3(COUNTER)
You are assigning to STRING an array element from VAL3.
What did your original code look like before you changed it?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OK, this is the original code (any code tags available here btw?):
SUBROUTINE MYFUNC (VAR1, VAR2, VAR3, VAR4, Z1,Z2, MN,
+ VAR5, VAR6, VAR7, FHLVAR)
CHARACTER*(*) VAR1
CHARACTER*(*) VAR2
INTEGER VAR3
CHARACTER*(*) VAR4
CHARACTER*(*) VAR5
! etc.
CALL ZSLES (VAR6, FNAME, FVALUE, IERR)
IF (IERR .NE. 0) GOTO 888
VAR1 = CHANGE ('VAR1', FNAME, FVALUE, IUMERR)
CALL ZSCHEC (FNAME, FVALUE, IUMERR, ISTAT)
IF (ISTAT .NE. 0) GOTO 999
! etc.
CHARACTER*(*) FUNCTION CHANGE (VARNAME,FNAME,FVALUE,IUMERR)
INTEGER IUMERR(*)
INTEGER ZCOUNT
CHARACTER FNAME(*)*(*)
CHARACTER FVALUE(*)*(*)
CHARACTER VARNAME*(*)
CHARACTER STRING*80
ZCOUNT = 1
DO 55 I = 1, 999
IF (FNAME(ZCOUNT) .EQ. ' ') GOTO 66
IF (FNAME(ZCOUNT) .EQ. VARNAME) THEN
STRING = FVALUE(ZCOUNT)
CALL CLEFT (STRING)
CHANGE = STRING
IUMERR(ZCOUNT) = 0
GOTO 99
END IF
ZCOUNT = ZCOUNT + 1
55 CONTINUE
66 CONTINUE
CHANGE =' '
GOTO 99
77 IUMERR(ZCOUNT) = 77
CHANGE =' '
99 RETURN
END
My primary task is to get this Fortran 77 / VMS code to compile with Intel 8.1.
I thought to have changed this code above due to the hints I got here so that it should work. Maybe I misunderstood, maybe some translation problems English-German produced some trouble.
Consider me a despoiled Java programmer ;) who has not been confronted with such variable declaration problems before.
If I understand it correctly, (one of) my problem(s) is
CHARACTER*(*) VAR1 which can not be translated for Intel 8.1 because it needs a number, not asterisk for unknown size, right?
SUBROUTINE MYFUNC (VAR1, VAR2, VAR3, VAR4, Z1,Z2, MN,
+ VAR5, VAR6, VAR7, FHLVAR)
CHARACTER*(*) VAR1
CHARACTER*(*) VAR2
INTEGER VAR3
CHARACTER*(*) VAR4
CHARACTER*(*) VAR5
! etc.
CALL ZSLES (VAR6, FNAME, FVALUE, IERR)
IF (IERR .NE. 0) GOTO 888
VAR1 = CHANGE ('VAR1', FNAME, FVALUE, IUMERR)
CALL ZSCHEC (FNAME, FVALUE, IUMERR, ISTAT)
IF (ISTAT .NE. 0) GOTO 999
! etc.
CHARACTER*(*) FUNCTION CHANGE (VARNAME,FNAME,FVALUE,IUMERR)
INTEGER IUMERR(*)
INTEGER ZCOUNT
CHARACTER FNAME(*)*(*)
CHARACTER FVALUE(*)*(*)
CHARACTER VARNAME*(*)
CHARACTER STRING*80
ZCOUNT = 1
DO 55 I = 1, 999
IF (FNAME(ZCOUNT) .EQ. ' ') GOTO 66
IF (FNAME(ZCOUNT) .EQ. VARNAME) THEN
STRING = FVALUE(ZCOUNT)
CALL CLEFT (STRING)
CHANGE = STRING
IUMERR(ZCOUNT) = 0
GOTO 99
END IF
ZCOUNT = ZCOUNT + 1
55 CONTINUE
66 CONTINUE
CHANGE =' '
GOTO 99
77 IUMERR(ZCOUNT) = 77
CHANGE =' '
99 RETURN
END
My primary task is to get this Fortran 77 / VMS code to compile with Intel 8.1.
I thought to have changed this code above due to the hints I got here so that it should work. Maybe I misunderstood, maybe some translation problems English-German produced some trouble.
Consider me a despoiled Java programmer ;) who has not been confronted with such variable declaration problems before.
If I understand it correctly, (one of) my problem(s) is
CHARACTER*(*) VAR1 which can not be translated for Intel 8.1 because it needs a number, not asterisk for unknown size, right?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Intel Fortran accepts all valid Fortran 77 code, and allows for CHARACTER(*) in the places it is normally allowed. But it does diagnose some errors that the VAX compiler did not. There's not enough of the program here for me to advise you as to what needs to change. You've left out declarations of the variables passed to routine CHANGE.
As for code tags - if you're using MSIE, there's a code button that lets you insert formatted code. Unfortunately this doesn't work in Firefox or some other browsers. I hope that will change soon.
As for code tags - if you're using MSIE, there's a code button that lets you insert formatted code. Unfortunately this doesn't work in Firefox or some other browsers. I hope that will change soon.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
sblionel wrote:
Intel Fortran accepts all valid Fortran 77 code, and allows for CHARACTER(*) in the places it is normally allowed. But it does diagnose some errors that the VAX compiler did not. There's not enough of the program here for me to advise you as to what needs to change. You've left out declarations of the variables passed to routine CHANGE.
To be honest, I didn't leave out the variables. They are not declared in the MYFUNC subroutine head nor in any global context. But they are used anyway - another suspicious issue I do not understand. Ah damn it, just found them in an included file. =:-|
CHARACTER*8 FNAME(60)
CHARACTER*40 FVALUE(60)
INTEGER*4 IUMERR(60)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ok - with those lines added, the only complaint I get from Intel Fortran is that CHANGE has not been declared as CHARACTER in the caller. If I added the line:
CHARACTER*80 CHANGE
to the declarations in MYFUNC, it compiled fine. What are you seeing?
CHARACTER*80 CHANGE
to the declarations in MYFUNC, it compiled fine. What are you seeing?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
sblionel wrote:
Ok - with those lines added, the only complaint I get from Intel Fortran is that CHANGE has not been declared as CHARACTER in the caller. If I added the line:
CHARACTER*80 CHANGE
to the declarations in MYFUNC, it compiled fine. What are you seeing?
Well...what can I say...finally works here too. *pretending some innocence by whistling some notes*
Thanks for pointing me to the error for which I deserve the "fool of the week"... ;-)
It was the missing declarations you mentioned recently which made me search for the reason why the compiler couldn't find the include file - it was in the wrong directory. And because it couldn't be found right at the start I just commented the include line out in the very beginning. :-o
Mea culpa... ;-)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm glad to hear that it's worked out.

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page