Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29246 Discussions

CVF -> IVF Conversion Problem - Strings

kyudos
Beginner
1,034 Views

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:

Do k = 1, 20

Name(k:k) = Dzrec.Name(k:k)

End Do

Name(21:21) = Char(0)

"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 - I'd rather not have to turn off the run-time checks altogether....
0 Kudos
7 Replies
mecej4
Honored Contributor III
1,034 Views
"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:

[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.

0 Kudos
Steven_L_Intel1
Employee
1,034 Views
Use CHARACTER(*) for dummy arguments.
0 Kudos
IanH
Honored Contributor III
1,034 Views
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.)
0 Kudos
mecej4
Honored Contributor III
1,034 Views
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]
0 Kudos
IanH
Honored Contributor III
1,034 Views
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?
0 Kudos
mecej4
Honored Contributor III
1,034 Views
> 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?
0 Kudos
kyudos
Beginner
1,034 Views

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]
0 Kudos
Reply