I'm starting to experiment with submodules in my mostly-F77 program, and am encountering an issue while trying to debug. I have a submodule defined in the usual way, and also have some files #included that define some COMMON variables. When I build the file and run it, things seem fine. But when I try to debug in GDB, I cannot examine the COMMON variables as GDB reports "no symbol <foo> in current context."
When I type "info locals", I receive a list of local variables, but the COMMON variables are listed as:
...the syntax for which GDB doesn't like when I try "print"-ing it. Is there a.) a trick to get GDB to allow me to inspect COMMON variables, and b.) (for purely academic interest) why are these symbols being renamed in the debugging table to include the module and submodule names?
associate (d_common_var => common_var)
continue ! place break here, use locally defined reference c_common_var
You can also use a pointer. In older versions of the compiler (pre-associate) I would use pointers initialized in conditional code for debugging aids.
@jimdempseyatthecove , unfortunately, ASSOCIATE is not a workable solution for me; the COMMON in question has a large number of variables, and more importantly, vectors.
But if I understand your subtext properly, does that mean that a COMMON defined in a SUBMODULE (or even just a module?) has different linkage than one defined elsewhere?
MODULE MY_MODULE INTERFACE MODULE SUBROUTINE MY_SUBMODULE( VAR1, VAR2 ) BIND(C) USE, INTRINSIC :: ISO_C_BINDING INTEGER(KIND=C_INT32_T), INTENT(IN) :: VAR1 INTEGER(KIND=C_INT32_T), INTENT(IN) :: VAR2 END SUBROUTINE MY_SUBMODULE
SUBMODULE (MY_MOD) MY_SUBMODULE__ CONTAINS MODULE PROCEDURE MY_SUBMODULE IMPLICIT NONE INTEGER*4 MAX_VAL COMMON/MEMORY_PARMS/ MAX_VAL MAX_VAL = 1 END PROCEDURE MY_SUBMODULE END SUBMODULE MY_SUBMODULE__
gdb ./test_program (gdb) p max_val No symbol "max_val" in current context. (gdb) info locals my_module@my_submodule__::max_val = 0 <...> (gdb) p my_module@my_submodule__::max_val A syntax error in expression, near '@my_submodule__::max_val'.
Then (I haven't tried this) in place of the associate, place a CALL DEBUG_xxx()
Where DEBUG_xxx is a CONTAINS subroutine in the module (xxx). This may provide the variables in the scope of the subroutine to be examined without decorating it with somewhere@something.
Note, I've seen where the compiler won't generate debug symbols for the variables not used in a procedure (IOW placing them out of scope). This would be an easy experiment for you to try.
You may want to also inquire about this at the Fortran Discourse site (https://fortran-lang.discourse.group/) and with the GNU community, for the matter may have more to do with some details/tricks or issues with GDB than possibly with Intel Fortran. You may find the input by readers on such forums more relevant to your inquiry.
With Intel Fortran and its integration with Visual Studio, a variable in a named COMMON in a submodule implementation appears the same as in external procedures, the far more common scenario (!).
Submodules are one of my favourite additions in the later Fortran standards and I use them extensively. I have no experience with common and modules, it is some years since the use of common block disappeared from my code to be replaced by modules. The problem you have is one of the debugger integration in visual studio which has several problems of this nature. However, if you are going to make use of submodules I would suggest that goes hand in hand with elimination of common blocks and all those common block include files. It depends on the way your program uses common if the same block is used to map different variables in different places you have a large task that may or may not be worth fixing. If you are just sharing some variables across a bundle of routines then having the the common as module variables and then grouping your routines that use those variables in submodules of that module is often not a big task. You only need interfaces for those routines used external to the module or used across sibling sub-modules you don't need to create interfaces for every routine in general.