- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Derived type:
TYPE MixerData
LOGICAL :: Exists=.false. ! True if there is a mixer (only 1 allowed per loop)
CHARACTER(len=MaxNameLength) :: Name=' ' ! Name of the mixer
INTEGER, ALLOCATABLE, DIMENSION(:) :: NodeNumIn ! Node number for the inlet to the mixer
END TYPE MixerData
Initialization:
TYPE (MixerData) :: MyMixer=MixerData(.false.,' ', ???)
What does one put where the ??? are for an unallocated array or can you not do that?
Linda
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Null() generates an error. What is the keyword specification? e.g., Exists=.false.? I have not seen this in fortran specifications.
If you make a variable based on a derived type (not allocated), some compilers don't seem to like just a simple variable without saying SAVE. Others accept it. Just trying to satisfy many compilers.
Linda
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
First, it seems the keyword syntax in structure constructors is a F2003 feature we don't yet support. (I will have to verify that when I get back to the office on Monday, I can see that it does not work.)
You cannot use an initialization expression to initialize a derived type containing an allocatable or pointer. You can provide default initialization in the type declaration which you did already - there's no point in saying it again.
You DO need to add SAVE to the declaration of MixerData if you want it saved - default initialization in a derived type does not imply SAVE and the variable will otherwise get reinitialized on each entry to the routine. This is a tricky point of the language that some compilers may not get right (in the past we didn't either, but we do now.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
To clarify, the MyMixer variable is a module variable, not a routine variable. Yes, I would add a SAVE automatically to the routine level variable. Some compilers insist on that in the module level as well.
Thanks for looking.
Linda
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Not sure about IVF (I'm not sure what compiler options I have turned on there) -- CVF complains if you put a SAVE in a module level...
"Warning: the SAVE attribute may only be declared for objects in a subprogram."
Linda
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>> Technically, you should add SAVE to the module variable if there could ever be a chain of active routines where none of them USE the module.
???
If you have a chain of active routines where none of them are USEing the module then there is no reference and therefore no requirement to initialize nor save that which is not referenced.
If any of a chain of active (or inactive)routines within an assembly contain a USE for a module, thus linking in the USEglobal data (if declared) and the contains functions (if declared), and the accompanying initialization code if defined and declared. Once loaded and initialized it is persistant with the execuitable.
That said, if you were to declare an instance of a derrived type within a subroutine (as opposed to inside the module dataportion of the module) then SAVE would be requied to maintain persistance.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Linda,
If you are unable to specify no allocation and if you do not wish to waste memory on allocating your working storage when not require then why not allocate to an unusable size. e.g. allocate to say 1. And then in your code where test for ALLOCATED follow it with a test for SIZE of 1 (as an indication of not allocated to the correct size).
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I understand your confusion, but the standard (F2003 here) sez:
(3) When execution of an instance of a subprogram completes,
(a) its unsaved local variables become undefined,
(b) unsaved variables in a named common block that appears in the subprogram become undefined if they have been defined or redefined, unless another active scoping unit is referencing the common block,
(c) unsaved nonfinalizable local variables of a module become undefined unless another active scoping unit is referencing the module, and
(d) unsaved finalizable local variables of a module may be finalized if no other active scoping unit is referencing the module following which they become undefined.
NOTE 16.18
A module subprogram inherently references the module that is its host. Therefore, for processors that keep track of when modules are in use, a module is in use whenever any procedure in the module is active, even if no other active scoping units reference the module; this situation can arise if a module procedure is invoked via a procedure pointer, a type-bound procedure, or a companion processor.
I don't know of any implementation that would actually lose the value of a module variable that is not SAVEd, but the standard says it could happen. Note that the standard has said this about COMMON blocks "forever" and this WAS a real possibility back in the era of "overlays" where sections of a program were brought in from disk as needed wiping out existing memory.
I'll admit that even I don't go adding SAVE to my module variables, but if it was possible for a module to go out-of-scope, I should do so if I wanted to ensure that the variable remained defined. (Note also that just because the value is undefned that doesn't mean it changes value - only that you can no longer depend on the value.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve,
Sez this:
>> (c) unsaved nonfinalizable local variables of a module become undefined unless another active scoping unit is referencing the module, and
This would seem to refer specifically tolocal variables within subroutines and functions in the CONTAINS section (but they you couldn't access them via USE in an application).
>>a module is in use whenever any procedure in the module is active
The keyword above is procedure (process). A procedure has birth, life, death. Where the USE data gets constructed during the birth and destroyed during the death. Typically an application is but one procedure (process)and therefore the USE data is persistent through-out the application. A procedure (on most systems) has one virtual address space (which may be spread across several processors).
This said, some "applications" consist of collections of procedures with one procedure typically acting as a control procedure but it could also be setup without designated controlling procedure. Each of the procedures have separate virtual address spaces, however with mapping techniques such as a Memory Mapped Files it is possible that portions of the (or each) process reference common data (potentially the data within the USEed module). Under this circumstance it is possible for the procedure to die while the application lives. I think this is what NOTE 16.18 is referring to.
There is also the situation where an application proceedure (process code), built to run stand alone, is loaded within one virtual addres space together with other procedures, also built to run stand-alone, where the controlling application calls the C runtime initialition coded of each procedure as opposed to the _main.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In this context, "local variables of a module" means module-level variables, not those within module procedures (which are not module variables.)
The note I cited applies to the F2003 feature of procedure pointers, which Intel Fortran does not yet support. It's saying that a compiler can't rely on simple lexical scope to determine where a module is or is not in use.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>It's saying that a compiler can't rely on simple lexical scope to determine where a module is or is not in use.
Precisely.
This is similar to potential problems of pointer to array
aPointer = aFuncThatAllocates()
call SomethingThatDeallocatesAbove()
aPointer.member=boink
When you have procedure pointers (where multiple procedures share the same virtual address space) you would have a similar problem (pseudo code)
ProcedureReference = SpawnProcedure()
pDerivedType => ProcedureReference.GetModuleDataReference()
... ! procedure terminates here and module data goes away !
pDerivedType.member = boink
Jim
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page