This has been driving me nuts for hours.
I’m very new to fortran (mostly used to python) and I’ve been creating a mesh generator for cfd.
I got it all finished and then decided I wanted to make everything double precision.
I have a module that defines the ‘dp’ parameter and its used in my main init program.
In all the other modules it recognizes, but it won’t on this program.
Even chatgpt and deepseek can’t figure it out its crazy.
This is the error:
I don’t think it’s something directly related to the dp kind parameter, but more of something happening earlier that makes the parser fail as soon as it encounters the r of the real declaration statement.
Chech everything comung earlier carefully.
I’m pretty sure it has at least something to do with it because I changed it to r64 and it works fine now.
program Project1Init
use iso_fortran_env, only : real64
use MeshInitialziation
use Boundaries
use DefineMesh
implicit none
integer, parameter :: r64 = real64
type(Mesh) :: m1
real(r64) :: y_lower,y_upper
real(r64) :: x_left, x_right
integer :: num_args, ios
integer :: i_max, j_max
Keep in mind, I tried doing the same thing but just with dp instead of r64, and it said something about “ambiguous term”?
I don’t know.
It works fine with this shoddy quickfix, but it’s still annoying to me to not know whats going on.
I did. I went and tried to make a MRE, and I found that by deleting the line use Boundaries it fixed. In the boundaries module I had made another dp parameter because DefineMesh wasn’t used in that module. I went ahead and added
use DefineMesh, only : dp
implicit none
private :: dp
to the boundaries module to fix it and it worked!
Thanks for the suggestions guys.
This statically typed stuff is really kicking me right now.
But this program was just a rewrite of a python script and it did in half a second what took python 20 seconds, so I’m glad to learn it.
Cheers!
Many fortran programmers do this as standard practice. With this programming style, you can look at the USE statements to see exactly where each parameter, variable, and subroutine comes from. With many modules in use, that can be quite a challenge otherwise.
I would add make everything in a module private by default except what you know you need to share with the rest of the world. Those you explicitly declare public. I know it can be tedious declaring things public if you have a lot of variables or routines you need to share but its only tedious once if you plan and program carefully. This approach coupled with using ONLY really cuts down on conflicts among modules and procedures
I have done this in a few of my modules, and it is actually more tedious that just doing it once. Every time a new entity is added to the module (a new derived type, a new variable, a new subroutine), then you must add it to the public list. I have, countless times, added something to a module, recompiled my program, and I get the error that something is not available from the module. Then I go back, realize it needed to be added also to the public list, and then it works.
Another way to have designed this feature would have been public and private blocks of a module. Everything in a public block would be public by default, and everything in a private block would be private by default. That would probably have been a better approach, but after all these decades, I think we are stuck with the current one-by-one approach.
Totally agree with this but as you say we are stuck with what we have for now. Also, I seem to remember some mention somewhere of some recent changes that address the public/private status of entities in modules USED by other modules that allow you to specify public or private on the used module without having to add that modules public or private entities to the parent modules public or private list. I probably have this all wrong since my memory isn’t what it used to be but I do seem to remember something was changed along those lines.
module mod1
use ISO_C_BINDING
integer :: dummy = 0
end module mod1
module mod2
use mod1
implicit none
private
public :: mod1
...
end mod2
The ifort/ifx and flang-new compilers support it, although with ifort/ifx nesting is a hit-or-miss —i.e., something USEing mod2 will see dummy but might or might not see symbols from the ISO_C_BINDING module.