- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
At the end of last week my Visual Studio 6 died on my 64-bit XP Machine. I've tried reinstalling it but it still crashes everytime I try to open a file. The project can be selectedbutVS6 also crashes when loading project files.
CVF had been working quite happily on the same computer for over a year. The reasons Icontinued touse it were mainly because I prefer the resource editor in VS6 to that in VS2008 and the 32-bit application is the one used by my customers for over ten years.
For customers with 64-bit machines I have successfully used IVFand both variants of the program show consistency in their function and output etc.
My first thought was to simply finally drop CVF and switch to IVF for all versions (something I meant to do anyway so that new features can be adopted in the future releases) but unfortunately the IVF 32bit Release compiled version of my program crashes.
32bit debug, 64bit release & debug versions all seem to work fine. I uselots of allocatable user defined types that have allocatable components and it is during deallocaton of one of these that the program crashes. I identifid the cause by adding write statements at various places within the code.
During my debugging sessions (on release configuration) I came across a few dodgy programming quirks that I would like to discuss.
For all dtat types I write a module that manages all instances within the program. The module contains routines to allocate, copy instances (using operator module procedure), increase/decrease size (not using reallocate) and deallocate.
1) Is using the UBOUND function on an unallocated array or data structure a safe thing to do? It returns 0 which suggests it works but maybe inconsistent on other computers.
2) What does allocating something ALLOCATE (x(0)) actually mean? This caused problems on CVF as the ALLOCATED(x) result would have been .false. but DEALLOCATE(x) would crash the program. I have no suchdeclarations in my code that I am aware of. ShouldIVF allow this.
3) In order to initialise a data structure I have a single instance of the structure with all components initialised as required. In the case of allocatable components I allocate to a minimum size. I then use a single statement to initialise the whole array. eg
type DATAT
integer :: b
real ::a
end type
type(DATAT),allocatable :: x(:)
type(DATAT) :: x0
x0%a = 0.0
x0%b = 0
allocate(x(100)) ! Line XX
x = x0
However if for some reason you don't firstly allocate x, eg by removing Line XX the program still allows the
x = x0. Is this correct?
4) optional arguments.Should the following statement be allowed? If not could either compiler or run time error be issued?
subroutine XXX(a,b)
integer,intent(in) :: a
integer,intent(in),optional :: b
if(present(b).and.b.gt.0) then
! Do something
else
! Do something else
endif
Although I've not got a solution to my problem yetI thought I'd bring these to everyone's attention for comment.
Any further advice would be much appreciated.
Steve
Link Copied
- « Previous
-
- 1
- 2
- Next »
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Suppose you have three or four calls to Solver with different functions that are also in different source files than the line in which the call is made. How do you ensure that every one of these functions has the correct interface, even if all that we have are implicit interfaces, without using compiler features such as the /warn of IFort?
I'm not sure I follow.
If the procedure being passed as an actual argument has an explicit interface then the processor can (should, and does with ifort) check that the characteristics of that explicit interface match an explicit interface provided for the dummy argument. It doesn't matter whether the dummy argument has been declared as per arjen's F95 method or by a PROCEDURE(abstract_interface) :: arg statement.
If the procedure being passed is external then the only way it can get an explicit interface (from a language point of view - ignoring compiler /warn:interface stuff) is if the programmer tells the compiler "trust me - this is the interface for this function". If the programmer gets that wrong they are in trouble - whether they use PROCEDURE(abstract_interface) :: external_proc or the full interface block.
I guess when you have multiple external procedures that you want to bless with the same explicit interface then using an abstract interface does save some typing and is less error prone as you only specify the full interface block once.
But then why are the procedures external in the first place? Just make every procedure a module procedure. But you know that...
John - many of the problems you describe with checking of argument numbers (and more), duplication of code, etc, disappear if you use module procedures. If you could modify the procedures code to include a USE statement for its own interface (if that were legal), then I don't see what stops you modifying the code to put the procedure itself into a module.
I think the only external procedures I have are either defined by C (or something other than Fortran) or (very occasionally) where I've needed to break some sort of cyclic module dependency. In the first case a module full of interface blocks makes a lot of sense. The second case should hopefully disappear when submodules become available.
Also, you talk about using SELECT CASE to select from explictly coded functions. I imagine in this case the "functions"would take the same (or similar) variables and return the same sort of result, but vary in the details of the internal calculation? Or to put it another way - they have the same external interface but vary in their internal implementation? If so, then much of F2003 is just providing inbuilt language support for patterns of usage that you are already familiar with.
It's not hard to see what is essentially "polymorphism" in use in F77 code. For one example that some on this forum will be familiar with, the way "streams" (material and information flows) were implemented in a popular (populus?) chemical process simulator - where the stream could be of different types. An integer variable (hollerith actually) told you what the type of stream is, based on that type you then interpret differently the meaning of various elements of several real and integer arrays that were otherwise opaque. Some elements of those arrays had common meaning regardless of stream type, some elements were common to subsets of stream types. It worked, but any code written to interface with it all was a mess. You can do the same thing today with F2003's features in a way that is so much simpler and clearer.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
> I'm not sure I follow.
Thanks for your comments; I have found it difficult to express myself clearly on this topic, perhaps because it is related to individual programming style (acquired from years of programming in F77 and C) not meshing well with new language features. I place emphasis on using libraries such as NAG and IMSL and making sure that procedure arguments passed to those libraries have the correct interface, which I realize is quite the opposite of John's position.
But, you have yourself provided the answer quite clearly, so I will merely quote you!
I guess when you have multiple external procedures that you want to bless with the same explicit interface then using an abstract interface does save some typing and is less error prone as you only specify the full interface block once.
> But then why are the procedures external in the first place? Just make every procedure a module procedure.Compilers often check implicit interfaces within a file (or all files compiled with one compiler invocation), and it is economical ( or lazy) to do it that way than write a separate module for those procedures in addition to writing the main driver program.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Your suggestion is interesting.
John - many of the problems you describe with checking of argument numbers (and more), duplication of code, etc, disappear if you use module procedures. If you could modify the procedures code to include a USE statement for its own interface (if that were legal), then I don't see what stops you modifying the code to put the procedure itself into a module.
I'm not sure where this would go. Like mecej4, I have always relied on static libraries when developing code, mostly my own. The implication would be to convert each library to a module and apply multiple use in the new code in each routine that requires the library modules. Each library module would then consist of the data definition then "contains" their routines.
The new code would then include USE statements for each "library" being called. I wonder how large and cumbersome the .obj files for the new code might become. Maybe the new compilers are smart enough to exclude all the unnecessary other info.
I'm yet to identify the benefits of CONTAINS, as I've always included the libraries at the link stage.
Would this approach guarantee argument checking ?
At present my use of ifort is in a dos box and my link command is a list of *.obj trees. I have not yet required the creation of static libraries. At present the libraries consist of multiple .for files, one for each procedure. Libraries appear to be an old-fashioned approach to programming. Isn't fashion great !!
Actually an easy way to implement this module approach might be to create a new file of the module and contains via a list of include statements. It will be interesting to see if I can identify any argument list anomalies.
The other alternative is to generate a new file "all.for" which is a list of INCLUDE 'xx.for' for all files in the project, although you could loose the flexibility of compilation options.
More argument checking at the link stage might have been a simpler approach, although this would not support mixed language programming. I don't think the Fortran language standard has properly addressed the linking process, although I am yet to fully read the 2003 and 2008 standards (or 1995).
John
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If a procedure is external, then the standard places no requirements on a compiler for argument checking at all. Most compilers will do some with appropriate debugging flags, but because the information available to the compiler is less, it is never going to be better than with module procedures.
Apologies - its not clear to me whether the static libraries (.lib) that you are using are yours (you have control of the source code) or third party. If they are third party libraries then ignore some of the following....
One static library can contain the object code from many modules. You end up with one lib file (that archives together many obj files - one for each compiled source file that goes into the library) and many mod files (one for each module - I typically have one module per source file so in my case the number of obj files and mod files is of the same order).
It may suit, though, to make life easier for the prospective users of your static library (which might be yourself), to have a top level module that USE's a selection of the other modules present in the libraries' source code and exposes just the procedures that the library's users should be calling (worker routines etc are still in modules, but these are not modules that would be typically USE'd by client code of the library).
To be clear - I'm not suggesting one module that has every procedure listed after the contains (unless the code is small) - instead it's a heirarchy of modules. Typically the lowest level of the heirarchy would group closely related procedures into a module. What closely related means is a judgement call, though there is a restriction that you cannot have circular module dependencies (i.e. an arrangement where module A USE's B, B USE's C, C USE's A is out - a related issue is that the source file that defines a module needs to be compiled before any source files that USE the module). That restriction aside, you could have every procedure in its own separate module, but that would be a bit of an administrative nightmare. Whether you have multiple modules per source file, one module per source file or one module split across several source files (by INCLUDE'ing bits together, in which case you don't separately compile the included files) is also up to you.
Higher levels of the heirarchy (if present) USE the modules in the lower level. They may have their own module procedures, or perhaps they just group and expose procedures (and types and variables, etc) from the lower level in a convenient way.
If you are not putting your own code into static libraries then there's no real difference in use. If you compile and link with one command line then I think you need to list the files in the right order (lowest level of the module heirarchy first).
Note that mod files are just for the compiler. They are not required at the link stage. I don't think the fortran standard even mentions the concept of linking (or mod files for that matter - that's all up to the various "processor" implementations). Others would know better.
The only downside to modules that I am aware of is that "compilation cascades" will result in increase build times (you make a change to a module that is at a low level in the heirarchy, all source files with program units that USE that module above it in the heirarchy need to be recompiled). In practice, my release builds have interprocedural optimisation turned on anyway, so I'd be getting a compilation cascade anyway even if I wasn't using modules. For debug builds it is occasionally annoying (with hundreds and hundreds of source files), but I deal with it. The submodules feature of F2008 should help fix this (which is why we all wait with baited breath for ifort 12.1/13/14/15/16...)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I somewhat disagree.
I find it more effective to split the source file of what would normally be a module with CONTAINS at the contains (removing the contains). Then add to thetop portion any INTERFACE blocks for what was in the CONTAINS. In the bottom portion, insert USE top portion in every subroutine and function.
The benefit of this, is during development of a large solution/project, if the interfaces do not change, but you edit the code section, then you do not need to re-compile ever routine that USEes the interfaces. Re-link - yes, re-compile - no.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The problem occurs when you change the argument list for a library routine. I try hard to avoid this but it does happen.
You then have to change the use of this routine in all projectsthat use this library routine. I would have in excess of 100 projects that use my own libraries, with most of them archived. The calling code is just as wrong as the INTERFACE code it contains. I need the discipline to USE a module of interface definitions that is defined with the library, not with the project. When recovering an old project and re-linking, you always hopethe programstill works and you can remember the changes that have taken place since it was developed.
I remember having this discussion with amember of the Fortran Comittee in 1985, relating to argument checking and the need to include the concept of linking in the standard. (Being on the other side of the earth, contact was infrequent and all we had then was fax) Back then the committee was constrained by the need to support old style mainframes from a major computer vendor. I don't think we now have a significant improvement in minimising these types of programing errors. Since then, Arrays has been the big change and MODULES some improvement on the industry prompted INCLUDE, but removing this error prone aspect of Fortran needed more direct action.
As for the origins of this thread,I can't see the implied initiation of Derived Types to be a good addition to the language for good programing techniques.
Anyway, this is what we have. Thanks for sharing your views.
John
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I somewhat disagree.
I find it more effective to split the source file of what would normally be a module with CONTAINS at the contains (removing the contains). Then add to thetop portion any INTERFACE blocks for what was in the CONTAINS. In the bottom portion, insert USE top portion in every subroutine and function.
The benefit of this, is during development of a large solution/project, if the interfaces do not change, but you edit the code section, then you do not need to re-compile ever routine that USEes the interfaces. Re-link - yes, re-compile - no.
In some cases maybe a variant of this is appropriate, but:
- You end up with "redundant" code - interface specifications in the module and then the subprogram specification section itself;
- You'd better be really careful that those interface blocks match the actual subprogram's code, because otherwise you've just landed yourself in a world of pain (the compiler will quite happily check calls to the procedure using an incorrect interface);
- With modern compilers implementing inter-procedural optimisation, re-linking means re-compiling to some extent anyway.
I say "variant", because I'm not sure if having an interface block for a procedure accessible inside the procedure that the interface block describes is legal. You might need to prevent use association of that procedures interface using an ONLY clause. Others may know better.
The code base subject to constant recompilation would need to be very large before I'd consider this worthwhile. If this sort of thing was on the table then I'd also be looking hard for options to reorganise the code base, such that development and testing could be undertaken on smaller pieces in isolation.
Submodules should help here - the code verbosity is more or less the same, but you get guaranteed checking of the declared interface in the module against the actual interface implemented in the submodule. Bring 'em on!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You said,
"I say "variant", because I'm not sure if having an interface block for a procedure accessible inside the procedure that the interface block describes is legal. You might need to prevent use association of that procedures interface using an ONLY clause. Others may know better."
I thought it is illegal. I'm suggesting it would have been a good alternative for the standard, such as in my example below:
[bash]module all_interfaces interface subroutine aa (v1, v2, v3) real*8 v1 real*8 v2 integer*4 v3 end subroutine aa subroutine bb (v1, v2, v3) real*8 v1 real*8 v2 integer*4 v3 end subroutine bb end interface end module all_interfaces subroutine aa use all_interfaces v2 = v1 ** v3 call bb (v1, v2, v3) end subroutine aa subroutine bb use all_interfaces v2 = v1 ** (-v3) end subroutine bb [/bash]
Although I have only 2 routines, there could be many more, with each routine taking it's argument definition from the INTERFACE definition module. That way, all routines in this librarycould have a single interface definition module which could also be USEd in the code that uses the library.
The aim is to not duplicate variable definition, which the present INTERFACE structure does, which I think you appreciate with yout comment :-
"You'd better be really careful that those interface blocks match the actual subprogram's code, because otherwise you've just landed yourself in a world of pain (the compiler will quite happily check calls to the procedure using an incorrect interface);"
When I read all the new complexity in 2003, I don't think what I am suggesting would have been too out there, as it would certainly lessen the pain.
I wonder who uses these 2003 structures. Probably all those who use Fortran .net.
John
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There are two issues at work here:
During development time, it is advantageous to eliminate the number of unnecessary builds. i.e. rebuilding files that USE a module where CONTAINS code may have changed but interfaces have not. In large projects, this can add minutes to each cycle of edit/build/debug, edit/build/debug, ...
After development, the code is (may not)generally not distributed (e.g. MKL), leaving just the INTERFACE file(s). If you use the two file technique, then you already have the interface-only files and you are not maintaining two copies.
When you concern is, as you exampled, adding an argument to a library call, I would suggest creating a generic interface, one with the extra argument(s), one without. The one withoutcallsthe routine with the extra argument andsupplies a default argument. This eliminates the need to edit the calls that have no need (or meaning)to supply the extra argument. When the call requires using the extra argument, then you add the argument to the call. In the cases where all calls must have the additional argument then require that (those) arguments on all INTERFACEs.
>>I can't see the implied initiation of Derived Types
It is there for those who want/need this type of initiations. Don't use it if you don't need it.
At times I can see a need for a CTOR/DTOR type of functionallity where a user supplied function/subroutine is (optionally) called at creation the distruction of object. Apparently you can use
type mytype
[...]
contains
FINAL :: finalize_subroutine
end type mytype
for dtor, but I am not sure about CTOR
You can use something like http://fortwrap.sourceforge.net/ for CTOR
But that is an indirect way (calling C++ to call back to FORTRAN to do the ctor)
A better method might be
type mytype
[...]
contains
INITIAL :: initialize_subroutine ! not in standard
FINAL :: finalize_subroutine
end type mytype
As the above would add orthoganality
I also found this: http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/b3580ffd988330d7
The above seems to indicate you can create a "member function" with same name as type namebut containing an argument list declared differently from the type data layout. Essentially making a generic interface out of the type name(I have not tried this as I do not have F2003/F2008)
Jim Dempsey

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page
- « Previous
-
- 1
- 2
- Next »