- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In my old CVF prject I had run time array bounds checking turned on in my debug build, and this setting was transferred when the project was converted to IVF.
I started to get "dummy argument islonger than actual argument" errors for some function calls, fair enough I can change to Character(*). But I got the same error on this:
"Name" is locally define as Character*21, Dzrec.Name is Character*20 (as part of aCOMMON structure).Do k = 1, 20
Name(k:k) = Dzrec.Name(k:k)
End Do
Name(21:21) = Char(0)
Why is that a problem? God knows how many similar constructs are scattered through the code - I'd rather not have to turn off the run-time checks altogether....
Link Copied
7 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
"Name" is locally define as Character*21, Dzrec.Name is Character*20 (as part of aCOMMON structure). Why is that a problem? God knows how many similar constructs are scattered through the code
That you say "why is that a problem?" indicates that you are in dire straits. I could state why that is a problem in terms of syntactic and semantic rules, but the following program should illustrate:
With the default optimized compilation, the result makes one suspect no problems.
S:\lang>bug
0.1000000
Compiling with /Od and running, we see bad news:
S:\lang>bug
9.9998474E-02
The error is small enough that, if you used a Format with fewer digits, you would not notice the error. It is large enough that in a calculation where five digit precision is insufficient the effect could be severe. If you got away with just a seg fault as a consequent of such defective programming, you should consider yourself lucky, since you received notice of a problem being present.
The language rules are there for a reason. If you break them and squirrel away the bugs where the compler cannot find them, you will be richly rewarded in ways that you do not expect.
That you say "why is that a problem?" indicates that you are in dire straits. I could state why that is a problem in terms of syntactic and semantic rules, but the following program should illustrate:
[fortran]program buggy implicit none character(len=8) :: str real :: x = 0.1 common /blk/str,x call sub() write(*,*)x stop end program buggy subroutine sub character(len=8) :: str common /blk/str str(9:9)=char(0) return end subroutine sub [/fortran]
With the default optimized compilation, the result makes one suspect no problems.
S:\lang>bug
0.1000000
Compiling with /Od and running, we see bad news:
S:\lang>bug
9.9998474E-02
The error is small enough that, if you used a Format with fewer digits, you would not notice the error. It is large enough that in a calculation where five digit precision is insufficient the effect could be severe. If you got away with just a seg fault as a consequent of such defective programming, you should consider yourself lucky, since you received notice of a problem being present.
The language rules are there for a reason. If you break them and squirrel away the bugs where the compler cannot find them, you will be richly rewarded in ways that you do not expect.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Use CHARACTER(*) for dummy arguments.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Could you please show the common block, variable and "structure" definitions and declarations, along with more details on the specific (runtime?) error message? I'm curious - because the error you describe doesn't seem relevant to the code you present.
(Note that declaring a structure using the STRUCTURE or RECORD keyword and the use of '.' as a component separator are processor extensions that have standard equivalents as of F90.)
(Note that declaring a structure using the STRUCTURE or RECORD keyword and the use of '.' as a component separator are processor extensions that have standard equivalents as of F90.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If he compiled with /check but not /warn, he would get the error that he described. A common block is not necessary. He declared a character(20) variable in the caller, but modified the substring (21:21) in the callee. For example:
[fortran]program charbug character(len=10) :: name name='1234567890' call sub(name) write(*,'(1H|,A,1H|)')name end program charbug subroutine sub(name) character(len=11) :: name name(11:11)='Z' return end subroutine sub [/fortran]Compiled and run with /check:all, gives
[bash]forrtl: severe (408): fort: (18): Dummy character variable 'NAME' has length 11 which is greater than actual variable length 10[/bash]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ok - I interpreted "locally defined" to mean a local variable, not a dummy argument. But in that case, doesn't any run time error traceback refer to the point of the function reference rather than the code in the function body that was presented?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
> doesn't any run time error traceback refer to the point of the function reference...
It does, but I did not display the traceback.
cbug.exe 0003106D _MAIN__ 4 cbug.f90
However, the extra checks brought in by /check get control before the access violation occurs and causes the traceback. I don't know the internals of the run-time, but it would be reasonable for the checking code to print its "severe error" message at subroutine entry and then immediately call the traceback handler, before the statement that could cause access violation is executed.
It seems to be a not infrequent belief that declaring a new size for a dummy (formal) argument of assumed size changes the memory allocated to that argument. That is how I interpreted the statement in the first post of this thread:
>"Name" is locally define as Character*21, Dzrec.Name is Character*20 (as part of aCOMMON structure). Why is that a problem?
It does, but I did not display the traceback.
cbug.exe 0003106D _MAIN__ 4 cbug.f90
However, the extra checks brought in by /check get control before the access violation occurs and causes the traceback. I don't know the internals of the run-time, but it would be reasonable for the checking code to print its "severe error" message at subroutine entry and then immediately call the traceback handler, before the statement that could cause access violation is executed.
It seems to be a not infrequent belief that declaring a new size for a dummy (formal) argument of assumed size changes the memory allocated to that argument. That is how I interpreted the statement in the first post of this thread:
>"Name" is locally define as Character*21, Dzrec.Name is Character*20 (as part of aCOMMON structure). Why is that a problem?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Could you please show the common block, variable and "structure" definitions and declarations, along with more details on the specific (runtime?) error message? I'm curious - because the error you describe doesn't seem relevant to the code you present.
Edit - BLAH - Ignore me, "NAME" is an argument to the function I'min - Character(*) is the way to go, if there are no compiler options to "make it work like it used to"
That is exactly my point!"Name" is a local variable 21 characters long. Why can I not copy the data from the common area? The error I get is:
forrtl: severe (408): fort (18): Dummy character variable 'NAME' has length 21 which is greater than actual variable length 20
Is there some hidden function call here that I'm not grasping?
The structure is as follows:
[fxfortran]cDEC$ PACK:1
Structure /Dz_structure/
Union
Map
Integer*2 Numzne
Integer*2 Desnum
Logical*2 Ok
Logical*2 VdesOk
Integer*4 Maxrec
Character*68 extra1
End Map
Map
Integer*2 Numnod
Integer*2 Numelm
Integer*2 Numflw
Integer*2 Numfix
Integer*4 Cv_loc
Character*20 Name
Real*4 Zflw
Real*4 Head
Integer*2 Onday
Integer*2 Onhour
Integer*2 Onmin
Integer*2 Offday
Integer*2 Offhour
Integer*2 Offmin
Logical*1 Desok
Character*1 Prv_here
Real*4 Thead
Logical*2 Novalv
Real*4 Velev
Real*4 Cu
Real*4 MeanEmitFlow
Real*4 Mean25EmitFlow
Integer*4 NumEmitters
End Map
Map
Character*40 Extra8
Real*4 Xhead
Character*36 Extra9
End Map
Map
Integer*4 End1
Integer*4 End2
Integer*2 Mains
Integer*2 Etyp
Real*4 Flow
Real*4 Head1
Real*4 Head2
Real*4 Cfact
Real*4 Length
Real*4 Minor
Real*4 Actdiam
Character*6 Unqid
Character*6 Junk
Integer*4 Obj_pid
Logical*2 Cmpsel
Integer*2 PRVus
Real*4 Elev
Real*4 MaxPress
Real*4 MaxSpot
Real*4 MinPress
Real*4 MinSpot
End Map
c
c have to do this since V5.1 of compiler doesn't allow nested unions !!!
c (V5.0 did !!!#@&*)
c
Map
Character*8 Extra4a
Integer*2 Prvusn
Character*14 Extra4b
Real*4 Minhed
Real*4 Maxhed
Real*4 Outlos
Real*4 Endhed(2)
Integer*4 Endoid(2)
Real*4 Dist(2)
Character*20 Extra5
End Map
Map
Character*50 Extra6
Integer*1 Ucflag
Integer*1 Ucrec
Character*28 Extra7
End Map
End Union
End Structure
Record /Dz_structure/Dzrec
c
c record for reading in (because of bug in compiler).
c Not needed now but we use this for reading old 64 byte records
c This way we don't need and old and new structure. New length is 80 bytes
c
Character*64 Tmprec
c
integer*2 warnings
integer*2 Num_prv
Logical*4 bRecl64
Common /dzcom1/Dzrec
Common /dzcom2/warnings,Num_prv,bRecl64
Equivalence (Dzrec,Tmprec)
cDEC$ PACK:
[/fxfortran]
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