- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
we have a large Fortran project containing also a large number of old Fortran 77 routines. Now two problems occured one with the 10.1 version, another with the version 11.1.046:
1. bound check
Environment:
Compiler: ifort (IFORT) 10.1 20080312
Flags: -O2 -check all -check noarg_temp_created -fpe0 -no-ftz -error-limit 5 -traceback -fpic -no-ipo -nus -sox -assume noprotect_constants
Debugger: totalview
Now the runtime check for the array bounds failed for a specific situation:
A subroutine called for example "sub1" uses automatic arrays, the problem occurs with the array "order":
This sub is called from outside
out --> sub1(maxc=15,..)
From within this sub, another routine "sub2" is called
sub1 --> sub2
Now this "sub2" calls, nested in some subcalls, again the routine "sub1" but with different array sizes
sub2 --> ... --> sub1(maxc=12,..)
This should be no problem, since the arrays are local, the debugger proves that the adresses are different for "order" in sub1 called from sub2 and from out.
The overall call sequence is:
out
--> sub1(maxc=15,..)
----> sub2 --> ... --> sub1(maxc=12,..)
----> .. --> back to sub2
--> back to sub1
But the bound check gives a runtime failure check with:
"Subscript #1 of the array ORDER has value 13 which is greater than the upper bound of 12"
This is definitiv not true, the debugger shows the array with an upperbound of 15.
And with the g95 compiler, this error does not occur.
We solved the problem by telling the compiler "-check nobound", but this should not be a final solution.
2. character length
Its not possible to use the new 11.1 compiler because with that version we get another crucial error with wrong character length:
subroutine cssngl(opcode,root,entry,column,single,error,*)
use m_cs, only: p_cs_common,cs_put_sngl,cs_get_sngl,cs_add_log
implicit none
character :: opcode
integer :: root
integer :: entry
integer :: column
integer :: single
integer :: error
if(opcode(1:1)=='P') then
call cs_put_sngl(p_cs_common,root,entry,column,single,error)
elseif(opcode(1:1)=='G') then
call cs_get_sngl(p_cs_common,root,entry,column,single,error)
else
error = -1
call cs_add_log(p_cs_common,"CSSNGL",error,"OPCODE INVALID")
endif
if(error/=0) then
return 1
endif
end subroutine
This is the call:
CALL CSSNGL('G',ROOBOU,1,5,IBMID(1),IDM,IERR,*99999)
What am I doing wrong?
Best regards,
Hendrik Dankowski
we have a large Fortran project containing also a large number of old Fortran 77 routines. Now two problems occured one with the 10.1 version, another with the version 11.1.046:
1. bound check
Environment:
Compiler: ifort (IFORT) 10.1 20080312
Flags: -O2 -check all -check noarg_temp_created -fpe0 -no-ftz -error-limit 5 -traceback -fpic -no-ipo -nus -sox -assume noprotect_constants
Debugger: totalview
Now the runtime check for the array bounds failed for a specific situation:
A subroutine called for example "sub1" uses automatic arrays, the problem occurs with the array "order":
[plain]c ----------------------------------------------------------------------
subroutine sub1(maxc,maxl,maxh,
* hdlins,limit,cols,lins,kcol,klin,coff,loff,yank,clear,
* hdtxt,ctype,cwide,cform,memoky,rdonly,trigger,order,
* iarray,rarray,larray,strbuf,sb,se,sl,icode,*)
IMPLICIT NONE
c arguments
integer maxl,maxc,maxh,hdlins
integer limit,lins,cols,klin,kcol,coff,loff,yank,clear,icode
integer cwide(maxc),order(maxc)
...
end subroutine[/plain]
This sub is called from outside
out --> sub1(maxc=15,..)
From within this sub, another routine "sub2" is called
sub1 --> sub2
Now this "sub2" calls, nested in some subcalls, again the routine "sub1" but with different array sizes
sub2 --> ... --> sub1(maxc=12,..)
This should be no problem, since the arrays are local, the debugger proves that the adresses are different for "order" in sub1 called from sub2 and from out.
The overall call sequence is:
out
--> sub1(maxc=15,..)
----> sub2 --> ... --> sub1(maxc=12,..)
----> .. --> back to sub2
--> back to sub1
But the bound check gives a runtime failure check with:
"Subscript #1 of the array ORDER has value 13 which is greater than the upper bound of 12"
This is definitiv not true, the debugger shows the array with an upperbound of 15.
And with the g95 compiler, this error does not occur.
We solved the problem by telling the compiler "-check nobound", but this should not be a final solution.
2. character length
Its not possible to use the new 11.1 compiler because with that version we get another crucial error with wrong character length:
forrtl: severe (408): fort: (18): Dummy character variable 'OPCODE' has length 1 which is greater then actual variable length -1077594976This is the called routine:
mtmonbot 08346C51 cssngl 11 cssngl.f90
subroutine cssngl(opcode,root,entry,column,single,error,*)
use m_cs, only: p_cs_common,cs_put_sngl,cs_get_sngl,cs_add_log
implicit none
character :: opcode
integer :: root
integer :: entry
integer :: column
integer :: single
integer :: error
if(opcode(1:1)=='P') then
call cs_put_sngl(p_cs_common,root,entry,column,single,error)
elseif(opcode(1:1)=='G') then
call cs_get_sngl(p_cs_common,root,entry,column,single,error)
else
error = -1
call cs_add_log(p_cs_common,"CSSNGL",error,"OPCODE INVALID")
endif
if(error/=0) then
return 1
endif
end subroutine
This is the call:
CALL CSSNGL('G',ROOBOU,1,5,IBMID(1),IDM,IERR,*99999)
What am I doing wrong?
Best regards,
Hendrik Dankowski
1 Solution
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
PDT is probably one of the last features we'll implement. It has been vexing for all of the vendors so far.
As for allocatable vs. static, allocatable arrays are allocated sequentially but there will be a small overhead due to having to look in the descriptor for address information. Most applications won't notice that.
Link Copied
15 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Please provide complete test cases for both issues. I can't tell what the problem is based on these excerpts.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Steve Lionel (Intel)
Please provide complete test cases for both issues. I can't tell what the problem is based on these excerpts.
I have a similar problem. Please see the attachement.
Thanks,
Zhanghong Tang
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - hdankowski
subroutine cssngl(opcode,root,entry,column,single,error,*)
CALL CSSNGL('G',ROOBOU,1,5,IBMID(1),IDM,IERR,*99999)
With certain compilers of many years ago, the argument mis-match would have a different effect. It's a little strange to claim that this code should "work" as long as you don't use an up to date compiler.
With any compiler, new or old, if you enabled interface checking, it would be a bug if the compiler didn't diagnose this and refuse to compile.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - hdankowski
Hi,
we have a large Fortran project containing also a large number of old Fortran 77 routines.
A subroutine called for example "sub1" uses automatic arrays, the problem occurs with the array "order":
we have a large Fortran project containing also a large number of old Fortran 77 routines.
A subroutine called for example "sub1" uses automatic arrays, the problem occurs with the array "order":
[plain]c ----------------------------------------------------------------------
subroutine sub1(maxc,maxl,maxh,
* hdlins,limit,cols,lins,kcol,klin,coff,loff,yank,clear,
* hdtxt,ctype,cwide,cform,memoky,rdonly,trigger,order,
* iarray,rarray,larray,strbuf,sb,se,sl,icode,*)
IMPLICIT NONE
c arguments
integer maxl,maxc,maxh,hdlins
integer limit,lins,cols,klin,kcol,coff,loff,yank,clear,icode
integer cwide(maxc),order(maxc)
...
[/plain]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Zhanghon,
You have a different problem - a coding error. When you called from C++ to Fortran, you failed to take into account that Fortran is expecing hidden arguments for character lengths at the end of the argument list. Since your C++ code does not supply this, garbage is picked up.
Add this line to the Fortran code after the declaration of name1 and name2:
!DEC$ ATTRIBUTES REFERENCE :: name1, name2
This tells Fortran to not expect lengths.
You have a different problem - a coding error. When you called from C++ to Fortran, you failed to take into account that Fortran is expecing hidden arguments for character lengths at the end of the argument list. Since your C++ code does not supply this, garbage is picked up.
Add this line to the Fortran code after the declaration of name1 and name2:
!DEC$ ATTRIBUTES REFERENCE :: name1, name2
This tells Fortran to not expect lengths.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In #1, sub1 is being called recursively, but it is not declared RECURSIVE. Thus, there is no reason for the compiler to set things up to keep track of multiple simultaneous values of maxc, so the most recent one "wins". (To keep things simple, some compilers generate recursive or reentrant code even if a subroutine is not declared RECURSIVE. On such a compiler, this error might be benign.)
In #2, you are passing eight actual arguments to a subroutine with only seven dummy arguments. In this case, I believe the result is that cssngl is accepting *99999 in place of the hidden length argument for opcode. (Although the end of the argument list is perhaps the most common choice for where to put character lengths, it is not the only one. For example, some compilers put the length as the argument immediately after the address of the character argument in the argument list. On such a compiler, this error might prove benign.)
In other words, both of these examples have programming errors that might still allow the program to "work" under some implementation models, while failing miserably under others.
-Kurt
In #2, you are passing eight actual arguments to a subroutine with only seven dummy arguments. In this case, I believe the result is that cssngl is accepting *99999 in place of the hidden length argument for opcode. (Although the end of the argument list is perhaps the most common choice for where to put character lengths, it is not the only one. For example, some compilers put the length as the argument immediately after the address of the character argument in the argument list. On such a compiler, this error might prove benign.)
In other words, both of these examples have programming errors that might still allow the program to "work" under some implementation models, while failing miserably under others.
-Kurt
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - hirchert
In #1, sub1 is being called recursively, but it is not declared RECURSIVE. Thus, there is no reason for the compiler to set things up to keep track of multiple simultaneous values of maxc, so the most recent one "wins". (To keep things simple, some compilers generate recursive or reentrant code even if a subroutine is not declared RECURSIVE.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - tangzhanghong98
I have a similar problem. Please see the attachement.
provides a standard means to avoid hidden character length arguments, so as to fix your argument parameter number mis-match.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - tim18
Fortran USE iso_c_interop
provides a standard means to avoid hidden character length arguments, so as to fix your argument parameter number mis-match.
provides a standard means to avoid hidden character length arguments, so as to fix your argument parameter number mis-match.
I think you mean USE ISO_C_BINDING, but that isn't helpful here as it is just a set of declarations. You're really thinking of BIND(C), and it SHOULD cause the compiler to avoid hidden arguments, but in today's release, it doesn't. It will in the update later this month (mostly) - be sure to read the release notes for details when it comes out. There are still some issues, such as with functions retiurning COMPLEX, where the compiler doesn't always do the right thing.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Steve Lionel (Intel)
Zhanghon,
You have a different problem - a coding error. When you called from C++ to Fortran, you failed to take into account that Fortran is expecing hidden arguments for character lengths at the end of the argument list. Since your C++ code does not supply this, garbage is picked up.
Add this line to the Fortran code after the declaration of name1 and name2:
!DEC$ ATTRIBUTES REFERENCE :: name1, name2
This tells Fortran to not expect lengths.
You have a different problem - a coding error. When you called from C++ to Fortran, you failed to take into account that Fortran is expecing hidden arguments for character lengths at the end of the argument list. Since your C++ code does not supply this, garbage is picked up.
Add this line to the Fortran code after the declaration of name1 and name2:
!DEC$ ATTRIBUTES REFERENCE :: name1, name2
This tells Fortran to not expect lengths.
Thank you very much for your kindly reply. If the Fortran code can't be modified, what should I do in C++ code?
Thanks,
Zhanghong Tang
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You need to pass the values 1 and 2 by value at the end of the argument list. I think this modification to stdafx.h would do it:
Those "int" declarations for size1 and size2 should really be some type that is 32-bits on a 32-bit system and 64-bits on a 64-bit system. I am sure there is a C type for that but I don't know what it is offhand.
[cpp]extern "C" void FTEST(int *n1, char *name1, int *n2, char *name2, double *a,double *b, int size1, int size2); // TODO: reference additional headers your program requires here class ctest { public: void mytest(int n1,char *name1,int n2,char *name2,double *a,double *b) { FTEST(&n2,name1,&n2,name2,a,b,1,2); }[/cpp]
Those "int" declarations for size1 and size2 should really be some type that is 32-bits on a 32-bit system and 64-bits on a 64-bit system. I am sure there is a C type for that but I don't know what it is offhand.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
long int is a 32-bit type on 32-bit linux, and 64-bit on 64-bit linux. Ditto for size_t, and some pointer types. I fear the reasoning here is obscure.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
thanks to all of you, it was very helpful!
#1: bound check
In fact the recursive calling of the routine was a llittle bit hidden. But anyway it works, the debugger shows that different (first adress) automatic arrays are allocated on entry. The code works perfectly, F77 allows recursive calling of function without explicitly stating this. I attached a screenshot from debugging, it shows the bound check error on the left ("order" of size 12) and the array size determined by the debugger on the right (15).
#2: character length
My fault, I didn't really see the wrong argument list. Surprisingly it worked for years .. but there are a lot dirty things possible with F77 :-)
Would be great if this can be checked by the compiler someday.
Let me finish with some further questions:
1. IIs there any plan in the near future to introduce parameterized datatypes (PDT)?
2. And is there actually any drawbank in performance by using allocatable instead of static arrays in regard of looping these arrays? I actually performed some simple tests and there was not much difference. Are allocatable array elements sequentially stored in memory?
Thanks again,
Hendrik
thanks to all of you, it was very helpful!
#1: bound check
In fact the recursive calling of the routine was a llittle bit hidden. But anyway it works, the debugger shows that different (first adress) automatic arrays are allocated on entry. The code works perfectly, F77 allows recursive calling of function without explicitly stating this. I attached a screenshot from debugging, it shows the bound check error on the left ("order" of size 12) and the array size determined by the debugger on the right (15).
#2: character length
My fault, I didn't really see the wrong argument list. Surprisingly it worked for years .. but there are a lot dirty things possible with F77 :-)
Would be great if this can be checked by the compiler someday.
Let me finish with some further questions:
1. IIs there any plan in the near future to introduce parameterized datatypes (PDT)?
2. And is there actually any drawbank in performance by using allocatable instead of static arrays in regard of looping these arrays? I actually performed some simple tests and there was not much difference. Are allocatable array elements sequentially stored in memory?
Thanks again,
Hendrik
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
PDT is probably one of the last features we'll implement. It has been vexing for all of the vendors so far.
As for allocatable vs. static, allocatable arrays are allocated sequentially but there will be a small overhead due to having to look in the descriptor for address information. Most applications won't notice that.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I just wanted to add my solutions to the described problems:
#1 array bound check: adding the "recursive" statement to the subroutine, even though this is not F77 std, fixed the bound check,
#2 the parameter calling list was wrong, correcting it fixed the problem.
Regards,
Hendrik
I just wanted to add my solutions to the described problems:
#1 array bound check: adding the "recursive" statement to the subroutine, even though this is not F77 std, fixed the bound check,
#2 the parameter calling list was wrong, correcting it fixed the problem.
Regards,
Hendrik

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