Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Sharing variables as an argument with Modules 1

Status
Not open for further replies.

JManuelR

Programmer
May 28, 2017
3
0
0
MX
Hello everyone,
I have the following problem, my main program calls subroutines that has arguments, those arguments are declared in a module but while compiling the following error appears:
Error: Symbol 'variable' at (1) has no IMPLICIT type
I dont know what is what I am missing here. I am pretty sure that is something really basic, but I'd been looking around and I cannot find the error.
I attached an example of the code that I am running. The following is the main program.
Code:
Program Various

Use Datos
Implicit None

call SRTN01(a,b,c)

Print *, a,b,c

End Program Various
This is the module.
Code:
Module Datos

Implicit None

Double Precision :: a,b,c

End Module Datos
And finally this is the subroutine.
Code:
 Subroutine SRTN01(a,b,c)

Use Datos
Implicit None

End Subroutine SRTN01
Every code is stored in a file independently of each other. Any help would be appreciated.
 
The arguments a,b,c of the subroutine SRTN01SRTN01(a,b,c) are not the same as variables a,b,c.

If you want that your subroutine changes only the variables a,b,c in the module, then remove the subroutine arguments.

For example
srtn01.f95
Code:
Subroutine SRTN01
use datos
implicit None

write(*,*) 'hello from SRTN01'
a=10
b=20
c=30
End Subroutine SRTN01

I named the module datos.f95 and the main program various.f95
It compiles and works now:
Code:
$ gfortran datos.f95 srtn01.f95 various.f95 -o jmauelr
$ ./jmauelr
 hello from SRTN01
   10.000000000000000        20.000000000000000        30.000000000000000
 
I forgot to say the I modified the call in the main program too:
Code:
...
call SRTN01
...
 
Thanks for your response mikrom

The thing here (and that I forgot to mention) is that the real code where I'm having the problem is much larger and with many variables. I was hoping that there could be a way to declare the variables "a,b,c" globally in a Module and use that as an argument in a subroutine. There are many variables that are used commonly between many subroutines. Otherwise I will have to track down all the variables and declare them locally. If there exist another way would be great.

Actually the error is:
Error: Name 'a' at (1) is an ambiguous reference to 'a' from current program unit

Sorry I was thinking that were the same error when I was creating the small example that I posted.

I'd been trying to solve it with the COMMON statement but wit not success.
 
I was hoping that there could be a way to declare the variables "a,b,c" globally in a Module and use that as an argument in a subroutine.
Yes you can do this with module.

Actually the error is:
Error: Name 'a' at (1) is an ambiguous reference to 'a' from current program unit
This happens when you for example use the same name for a subroutine argument and for the global variable
For example I have this subroutine:
foo.f95
Code:
subroutine foo(a)
use datos
a=1.0
end subroutine foo

When I try to compile this code I get the error you mentioned
Code:
$ gfortran -c foo.f95
foo.f95:3.1:

a=1.0
 1
Error: Name 'a' at (1) is an ambiguous reference to 'a' from current program unit
It is because the compile did not know if you want to assign 1 to the global variable a found in the module datos or to the parameter a of the subroutine. The names of the subroutine parameter and the global variable collide here.

The solution is to rename parameter of the subroutine, for example:
Code:
subroutine foo(x)
use datos
a=1.0
end subroutine foo
Then the compilation succeeds:
Code:
$ gfortran -c foo.f95
 
I'd been trying to solve it with the COMMON statement but wit not success.
This will work too, but the approach with modules is modern and simpler.
COMMON blocks are obsolete and error-prone.
 
I was hoping that there could be a way to declare the variables "a,b,c" globally in a Module and use that as an argument in a subroutine.
You mix global variables and procedure arguments together. But these are different things.
If the variables are global then you can use them in your subroutine. You don't have to pass them as arguments too.

But if you need, you can use both pass some arguments to the subroutine and use global variables in it too.

for example:
Code:
Module Datos

Implicit None

Double Precision :: a,b,c

End Module Datos

Code:
Program Various
Use Datos
Implicit None

a=1
b=2
c=3
Print *, a,b,c

call SRTN01(a+1, b+2, c+3)

Print *, a,b,c

End Program Various

Code:
Subroutine SRTN01(x, y, z)
use datos
implicit None
Double Precision :: x, y, z

write(*,*) '-- begin from SRTN01'
write(*,*) ' incoming argument values:'
write(*,*) x, y, z
write(*,*) ' module variables values:'
write(*,*) a, b, c
write(*,*) ' ... now modifying module variables'
a=10 * x + 1
b=20 * y + 2
c=30 * z + 3
write(*,*) '-- end from SRTN01'

End Subroutine SRTN01

If I compile and link these 3 sources and run the program I get
Code:
$ gfortran datos.f95 srtn01.f95 various.f95 -o jmanuelr

$ ./jmanuelr
   1.0000000000000000        2.0000000000000000        3.0000000000000000     
 -- begin from SRTN01
  incoming argument values:
   2.0000000000000000        4.0000000000000000        6.0000000000000000     
  module variables values:
   1.0000000000000000        2.0000000000000000        3.0000000000000000     
  ... now modifying module variables
 -- end from SRTN01
   21.000000000000000        82.000000000000000        183.00000000000000

As you see the subroutine SRTN01 has 3 parameters x, y, z and use the 3 global variables a, b, c too.
In the main program I set the global variables:
a = 1, b = 2, c = 3
and additionally I pass to the subroutine 3 arguments
x = a+1, y = b+2, z = c+3
then the subroutine computes new values of a, b, c.
 
Thanks again mikrom!!

Now I have a better understanding of what I can and I cannot do. I really appreciated.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top