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

passing costanct data to a function/subroutine

cecio
Novice
1,092 Views

Hi,

i'm trying to port my old CVF 6.6 programs to IVF using visual studio 2010.

My problem is that i intensively use to pass costanct data as a parameter calling function or subroutine:

...

K=ireardw(256,buf,ncan,ierr)

...

integer*2 function ireadw(nword,buf,nbloc,ncan)

 

if i declare nbytes variable as integer*2 i have correct value of 256 inside the function; if i declare it as i*4 i have a random(?) value.

How can i solve?

Thanks

 

0 Kudos
12 Replies
Les_Neilson
Valued Contributor II
1,092 Views
In your project settings under Fortran -> Data what have you got for Default Integer Kind ? If you have it set as 2 then your "256" constant is being passed as an integer*2 sized constant which would match your declaration of nword as integer*2 BUT if you declare nword as integer*4 and pass in "256" as an integer*2 constant then you can expect problems ! Including messing up the stack. Les
0 Kudos
cecio
Novice
1,092 Views
Hi Les, Default integer kind is 2, and it was 2 in all the old CVF projects too..... These kind of passing method is used in hundreds of colling instructions and i never had problems.... Why IVF dosen't put at 0 declared variables? Why you mention the stack? if i declare a I*4 (system reserve 4 bytes for it) and i put in it only 2 bytes how can i messing up the stack???? cecio
0 Kudos
Les_Neilson
Valued Contributor II
1,092 Views
If it is 2 in CVF then it needs to be 2 in IVF. Default integer is (these days) 4 bytes unless you tell the compiler differently. There may exist special compiler/machine combinations which do not have byte = octet (I seem to recall CDC machines have "words" rather than bytes - I may be wrong) Anyway. It is wrong for the programmer to assume that variables will be automatically given the value 0 at start up - but there is a switch to do so (for all local intrinsic type scalars) Such a mechanism is not Standard and not portable! It should be avoided It is the responsibility of the programmer to ensure that data have the correct values when the program is run. The stack is where the actual arguments are placed when you call a subroutine or function. The stack clean up move the stack pointer up or down according to how much data has been placed on or removed from the stack. If you lie to the compiler about the size of the data that has been put on the stack then the stack pointer will be corrupted and you will probably end up with data corruption and/or an access violation. Les
0 Kudos
Steven_L_Intel1
Employee
1,092 Views
The Intel compiler allows you to pass a constant of a larger kind to a smaller one, but by default you'll get an error from the generated interface checking about the mismatch. You won't mess up the stack by passing the wrong kind. My advice is to explicitly specify the kind on the constant, such as 256_2 . It is possible to turn off the error checking, but I think that the added risk you take by doing so is not worth the benefit.
0 Kudos
Les_Neilson
Valued Contributor II
1,092 Views

Steve Lionel wrote:

The Intel compiler allows you to pass a constant of a larger kind to a smaller one, but by default you'll get an error from the generated interface checking about the mismatch. You won't mess up the stack by passing the wrong kind.

Is it the same for /iface:cvf ? The OP says the code came from CVF originally, maybe he has this setting. Les

0 Kudos
cecio
Novice
1,092 Views
In facts it is 2 now and it was 2 in CVF. I partially agree your considerations ... I agree is not good to pass value directly rather than variable, but, fortran philosophy is to be strictly BYREFERENCE. So, if i call a subroutine with first parameter declared i*2 and in the subroutine i declare the first parameter as I*4 i expect that the first 2 of these 4 bytes are the same passed by the calling program. Your considerations about stack corruption doesn't apply to this case, i think. I try this: k=ireadw(256,buf,nbloc,ncan) ... integer*2 function ireadw(nword,buf,nbloc,ncan) integer*4 nword,mlog integer*2 ilog(2) equivalence (ilog,mlog) mlog=nword write(*,*) ilog(1),ilog(2),nword ... ... the result is -16864 -16432 459008 !!!!!
0 Kudos
cecio
Novice
1,092 Views
Hi Steve, in my program i do the reverse.. i pass a smaller constant (256) to a bigger variable ( I*4) and i don't have any message. But... why doesn't work?
0 Kudos
cecio
Novice
1,092 Views
Les, Calling convention is set to /iface:cref
0 Kudos
cecio
Novice
1,092 Views
Steve, Les, I made a mistake. in my test the result is 256, 7, 459008!!! That is i expect if the compiler doesn't put at 0 the i*4 variable instantiated.
0 Kudos
Steven_L_Intel1
Employee
1,092 Views
Please show us a complete test case - I can't tell what you're doing from these snippets and paraphrases.
0 Kudos
cecio
Novice
1,092 Views
Hi Steve, since I can not have doubts about the correct results I decided to change all the old sources to conform to the new rules (which are certainly more formally correct) and then will replace all constants with variables passing data between routines. Thanks. Cecio
0 Kudos
jimdempseyatthecove
Honored Contributor III
1,092 Views
>>in my program i do the reverse.. i pass a smaller constant (256) to a bigger variable ( I*4) and i don't have any message. But... why doesn't work? This would be a quirk of an implimentation issue. With default integer size = 2, depending on implimentation (and processor), the parameterized may be stored in 2 bytes of memory or in "word" size chunk of memory (2, 4, 8, other). On call (by reference) the address of the argument is passed. If the callee assumes integer*4, then it assumes the reference is that of a 4 byte integer variable. When the implimentation stores an integer*2 parameter in 2 bytes then the additional 2 bytes of the integer*4 are undefined (but may be ascertainable to the programmer). Should the implimentation (and CPU) NOTsupport 2 byte accessefficiently and elects to store integer*2 parameters in 4 bytes, then (and only then) is the calling convention ereror hidden (i.e. your program works with bugs and all). Jim Dempsey
0 Kudos
Reply