- 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