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

Function arguments are not private?!?!?

anishtain4
Beginner
1,020 Views
I have installed visual studio 2008 and intel visual fortran compiler version 11.1 on it. When i wanna use function interestingly argumants of the function are not private and when they change any variable with that name inside the body of program changes!!, what is really bothering, is there any option that makes it to LOGICAL default? I know how to write private on a subroutine but I need something stronger, it's annoying to write private for every function you have.
0 Kudos
10 Replies
lklawrie
Beginner
1,020 Views
You probably should send a snippet of your code to illustrate.

"what is really bothering, is there any option that makes it to LOGICAL default?" -- I'm not sure what you are asking here -- do you want the function to be logical or variables or?

Linda

0 Kudos
anishtain4
Beginner
1,020 Views
I replied yesterday I don't know why it's not here, anyway.

My problem is with this simple piece of the code:

program test
implicit none
real::a,b
a=1
b=2
call prn(a)
contains
subroutine prn(a)
print*,b
end subroutine
end program test

As you see this program should return an error since b is not defined in subroutine prn but amazingly the printed number on the screen is 2!!! that means the variable in the body of program is being used in scope unite of the subroutine and this makes a lot of problems for me in long programs where there are a lot of functions. The major problem occures when multiple threads are running and using different functions or routines and all of the variables are global, As you see it becomes a mess!!!
My question is how should I make all the variables to be private?!?!
I tried to write "private" in subroutine but it says this scope can only be used in module and I don't know how to use module?
0 Kudos
bendel_boy1
Beginner
1,020 Views
CONTAINS defines subroutines & functions that are internal to the main routine, and therefore can inherit variables from the containing routine. This is why your variable 'b' is accessible inside PRN.

If you wrote your code as

program test
implicit none
real::a,b
a=1
b=2
call prn(a)
end program test

subroutine prn(a)
implicit none
print*,b
end subroutine

then you would get the behaviour that you are expecting.

There are several good text books on Fortran 95/2003, and it may be that you need to take the time to read one. You can also find free online tutorials for Fortran 90/95, which may be sufficient for your needs. You can locate the free resources with a web search, and the Fortran books by consulting your favourite on-line book seller. Bookshops rarely stock Fortran material, unless you are fortunate enough to have a university bookshop close to hand.

0 Kudos
ralf_schaagmail_com
1,020 Views
You are using the variables in your subroutine in a "host-associated" context - what you are observing is intended like that. Variables can bedeclaredprivate only in a module.
In the example below there is an error message - changing "print*,b" to "print*,a" compiles without error (note that they both have no user-defined values assigned):
module mod_test
implicit none
real, public :: a
real, private :: b
end module mod_test
program test
use mod_test
implicit none
print*, b
end program test
Modules can do more, like containing subroutines and functions - there are lots of tutorials available online.
Cheers
-Ralf
0 Kudos
Les_Neilson
Valued Contributor II
1,020 Views
Asmall detail about the wording of your question.
prn is a subroutine not a function.
The variable "b" is not a "Function argument" nor a Subroutine argument, it is (as someone else has already pointed out) visible to the subroutine prn by host association.

Confusinglyyou have "a" astheDUMMYargumentof subroutine prn,
theACTUAL argument in "call prn(a)",
AND visible to prn by host association.

In fact you could have
subroutine prn(x)
where"x" isthe dummy argument and "prn" can be "called" with any valid *actual* argument.
call prn(a) ! actual argument is a
call prn(b) ! actual argument is b



Modules are quite easy and I would recommend that you learn them

module my_module
real :: a
real :: b
end module my_module

program test
use my_module ! test has access to both "a" and "b"

a = 42.0
b = 3.14159

call prn

end program test

subroutine prn
use my_module, only :b ! now prn only has access to"b"
print *,b ! printthe value of b
end subroutine prn

Les
0 Kudos
anishtain4
Beginner
1,020 Views
Yeah I got the point, Thanks all. My problem is that the version of fortran I was working with before considered all the variables inside functions and routines as pirvate (I think that is against the standard) and I was quiet used to it.
I'm trying to use modules they are really good, so I can use the codes I write in numerical analysis again in LES simulation or else. I have some more questions though; if I define a module like this:

!start of module file
module funcs
implicit none
end module funcs

integer function A(x)
integer,intent(in)::x
---come codes
end function A

subroutine b(x)
integer::c
y= A(c)
--some statements
end subroutine
!end of module file

it says that the type of A I called in subroutine b does not match, however when I put the function and subroutine inside the module and use contains this error does not show any more and everything works perfectly but I think portablity of my code (module in this case) will be better in this way!!

another questionI have is that can I put one module somewhere and use it in many different projects? So when I add another function all of the programs have access to it? When I put the module file in a same folder as the code is everything works well but when add it to another project it wont work with the module.

If I'm asking too much simple questions please introduce me a good reference for modules and you won't say "Wah, what a question" anymore ;)

Thanks
0 Kudos
Andrew_Smith
Valued Contributor I
1,020 Views
You have not put your functions inside the module but if you did do so then you would not need implicit none in each function.
0 Kudos
anishtain4
Beginner
1,020 Views
What if you write functions out of the module? should you add implicit none? Is that at all needed to write functions out of module?

I solved the problem of loading the module file but the problem of data type does not match is still there, what should I do for that?
0 Kudos
Steven_L_Intel1
Employee
1,020 Views
The difference is not really the "version of Fortran" but that you changed the code. If you compiled your original code with the new compiler, it would work the same, and local variables within functions would still be "private", as you put it. But when you take your functions and put them in modules or contained routines, then all the function names become visible to all the other functions in the module or host routine. Furthermore, any variables declared at module level or in the host routine are visible to all contained functions.

For more information on this, see the "Up Periscope" section here.
0 Kudos
Les_Neilson
Valued Contributor II
1,020 Views
(1) with seperate compilation, in subroutine bthe compiler doesn't know that the function A returns an integer and usesassumed type of real( variables beginning with letter A-H or O-Z are assumed real)
hint : always put "implicit none" statements in your code.

(2) yes with amodule you can "use" the module anywhere it is required. This is a huge advantage where you can specify all your (related) data variables ina module AND you can collect together all of the subroutines/functions that act upon that data in the module alsoand they are accessible to any subroutine/function that uses that module. This also allows the compiler to check whether you have the CALL correctfor the subroutines by checking the interfaces for you. (correct number and type of arguments)
One common scenario is to have routines that GET the contents of a variable and others that SET the contents, all in one module.


Many projects can refer to (i.e. USE)the samemodule. All you need to do is ensure that each project hasthe pathto that module.
See Project->Fortran->General->Additional Include Directories and
Project->Linker-General->Additional Library Directories

Les
0 Kudos
Reply