Silverfrost Forums

Welcome to our forums

Initialization to zero

20 Dec 2015 2:50 #17087

I’m working on a fortran program which was probably developed on a system that provided automatic initialization of variables and arrays to zero. On FTN95, this program generates many arithmetic errors.

Is there a compiler option to initialize local variables and arrays (not only saved ones) to zero?

Thank you in advance for any suggestion.

20 Dec 2015 3:38 #17088

/ZEROISE only works on statically allocated variables, so perhaps needs to be combined with the global /SAVE compiler option.

20 Dec 2015 6:33 #17089

Thank you. It could work, but I'm a bit scared of setting the global save, since there are subs that are called several times in a run.

20 Dec 2015 7:31 #17090

/SAVE means that they are not saved on the stack. A fixed address is used.

If the code is as old as you think, perhaps the code is written not to be recursive/re-entrant and /SAVE will work just fine.

/SAVE does not save the current contents, then reload the next time the code is run. You'll always start with a fresh copy.

21 Dec 2015 12:53 #17091

Both /ZERO and /SAVE are non-conforming for Fortran 95. Depending on how complex your code is, I would prefer to change the code to initialise all variables as they are being used. I have not used /ZERO, but this may make the .exe much larger and also initialise arrays that might not be used if there are different options in your program. /SAVE will also remove dynamic allocation of local variables/arrays and stop recursion.

It can be a personal preference, but I would never use /ZERO or /SAVE. I'd change the code to control where this is needed.

21 Dec 2015 3:02 #17092

John has a good point. It is ALWAYS best to do your own initialization.

When reusing old code, however, it might be a reasonable 'shortcut' to use both /ZERO and /SAVE so that you can get the code working in the shortest amount of time. This is especially true if it is not your code that you are working with!

21 Dec 2015 10:05 #17093

If it is old code, then it doesn't need to be Fortran 95 compliant, does it?

I agree that it is always best to initialise yourself, and it has been best practice to assume no initialisation and local variables don't retain their values.

22 Dec 2015 3:57 #17094

Thank you everybody.

I totally agree that the right thing to do would be initializing the variables in the code when they are used. However this is a complex code and it is not mine, so modifying it would require a lot of time.

If I understand correctly what wahorger said, /save option does not preserve the values of the variables between successive calls of the routines. Can you confirm this?

22 Dec 2015 5:49 #17095

Quoted from Emanuele However this is a complex code and it is not mine, so modifying it would require a lot of time.

Whether you modify the old code or not, you still need to ascertain whether it requires that some (or, perhaps, all) local variables need to be saved, and whether some (or all) variables need to be initialized to zero. Note, in addition, that if you have logical and character type variables initializing them to zero is a dubious thing to do.

If I understand correctly what wahorger said, /save option does not preserve the values of the variables between successive calls of the routines. Can you confirm this?

No, /save DOES preserve the values. That is the whole purpose of /save.

You may be a little puzzled by needing to use /zero when /save has been used. The /save option guarantees that when the subprogram is [u:28633a8fde]entered [/u:28633a8fde]the 2nd, 3rd, etc., time, the SAVEd variables will have the same values as they did after the same subprogram was [u:28633a8fde]exited [/u:28633a8fde]the 1st, 2nd, etc., times. Note that this does not cover the initial values of the same variables when the subprogram is [u:28633a8fde]entered [/u:28633a8fde]the 1st time. That is where /zero or user-supplied initialization comes in.

2 Jan 2016 4:36 #17102

Thanks and happy new year to everybody!

Quoted from John-Silver 2 thngs jump out at me ....

  1. it's not sure that the original program had automatic initialization of variables
  2. what ar these 'arithmetic errors' exactly

For example, there are a lot of array multiplications (element by element) in the program, but often only certain values of the arrays are initialized; so when the multiplication is applied between two undefined elements of the arrays I get an error. No problems - theoretically - if the arrays were initialized to zero, and that's one of the reasons why I suppose the original program had automatic initialization. But of course I cannot be sure.

3 Jan 2016 12:34 #17103

Just asking ...

Might there be a BLOCK DATA somewhere that isn't linked in?

I can't find any of the Fortran stuff that Les Hatton used to have on his website, but I do remember that he once advocated using named BLOCK DATA routines and declaring their names in an EXTERNAL statement as a method of making sure that the linker looked for it/them. I didn't like that much, but then I don't use BLOCK DATA for historical reasons - it wasn't available on several systems I used decades ago. (Instead I have an ordinary subroutine named BLOCK_DATA that gets called for every new problem).

3 Jan 2016 9:54 #17104

BLOCK DATA would be an excellent place to look, if you have it. I've been using it since the 70's. It is the only way to initialize labeled COMMON. BLANK COMMON might be able to be initialized in a program/module, but I steer away from BLANK COMMON.

I have a large number of COMMON blocks and many, many variables. I always initialize in the BLOCK DATA sub-program.

This does make the image to be loaded larger, but that is of no real concern.

I've used /SAVE and /ZERO. I may be incorrect, but I believe that /ZERO does not work for variables in BLANK or labeled COMMON. That is my experience, as I've been compiling in /CHECKMATE mode and had Undefined errors at run-time when referencing COMMON.

3 Jan 2016 11:22 #17105

I've been wondering how BLOCK DATA will work with FTN95 /64. In /64, SLINK64 allocates common a memory address at startup (which is fantastic as it removes the 2gb common size limitation) but I wonder what it does for BLOCK DATA initialised common ?

I can't recall a program I have developed that uses BLOCK DATA. I initialise most variables at run time, except for local variables/parameters that are in a data statement. For example I will typically code: ' LOGICAL :: first_call = .true. ' and utilise this as an indicator of first or subsequent calls.

Doesn't /ZERO make the .obj and .exe much larger ? May be when disk space was at a premium I developed a dislike for /ZERO.

I still avoid some code structures where there were bugs in earlier versions of FTN95. I've long tried to develop a safe coding style and it's hard to change. I probably once used a linker that had restrictions using BLOCK DATA. Many early compilers I used did not provide /Zero and I think Salford FTN77 on Pr1me was the first time I saw /zero.

John

4 Jan 2016 7:34 #17106

Here is an extract from the 64 bit beta installation notes...

Arrays that are ALLOCATEd, or which are in COMMON or in MODULEs can exceed the 4GB limit, except that initialised arrays must fit within the .EXE or .DLL file to which they belong, and the the size of these files cannot extend beyond the 4GB limit. This is a Microsoft limit, but is fairly reasonable, since the time needed to load a 4GB file would be excessive!

COMMON blocks and MODULE arrays are allocated dynamically as a program starts in order to enjoy no 4GB restrictions. This is applied to all such storage blocks, because a program may exceed the 4GB limit even though each individual array lies within this limit.

4 Jan 2016 9:53 #17107

Paul,

I assume that the space for COMMON blocks is allocated when a program starts, but thereafter the allocation is static for the whole program run.

John,

I liked your first_call idea, and decided that I would use it myself, until I realised that if I start a program with File | New I automatically initialise everything, and if I start from File | Open or a file association (I don't do 'drag and drop') then I initialise in a different way. I only use single document interfaces (SDI) so I know at any point (as if it isn't obvious from where in the program it is) from the grey codes in the File menu whether it is a 'start from nothing' run or not.

4 Jan 2016 11:37 #17110

That is also my assumption.

6 Jan 2016 7:06 #17115

Eddie,

I learnt to use Fortran using compilers that did not initialise memory. I was taught that failing to initialise variables and arrays is wrong and I still have that view, so I never use /zero.

However, although /save was not required back then, I have learnt to manage dynamic allocation of local variables in a subroutine and now consider all variables to be lost between calls, unless I explicitly save them. I don't like /save.

I will always use /implicit_none, which just goes to show that the use of all these options remains a personal coding preference and is not a RULE.

John

6 Jan 2016 11:06 #17118

John,

I detest /zero for reasons you adduce, and dislike /save because it debauches the clarity of the original Fortran:use COMMON, and variable contents are saved, define them locally and they aren't.

31 Aug 2017 3:54 #20078

If I may, I would like to continue with this thread and provide our compilation findings.

We have just moved from v6 to the latest v8.1 using the same compilation options of /WINDOWS /INTL /ZEROISE. We are now creating a DLL where in the past we created an EXE.

A user contacted us to say our software crashed. It turns out a local variable was undefined. v6 use of the /ZEROISE option worked fine for us and now there seems to be a difference in its use. Reading the current thread confirms what I found : using /SAVE resolved the initialisation concern. However, we are not wanting this as a solution due to the size of the product and also the potential for any other undefined local variables, using their last value.

So, looking thru the compiler options, we noticed /LOcal_zero which reads exactly what we want ' implies /ZEROise and also initialises local variables to zero when not using /UNDEF'. [ This is confusing, as you cannot have /UNDEF at the same time as /LO ]. Apart from creating an enormous product - just like using /UNDEF or /SAVE - this option did NOT solve our problem.

My question, Paul, is why did /LO not initialise local variables as /ZEROISE did in v6 ? Thanks

31 Aug 2017 4:36 #20079

Steve,

Reading what you wrote, is it possible that the problem arises through the use of a DLL instead of an EXE, and therefore is not a SAVE or ZEROISE issue? Have you compiled and run the old version software with 8.1?

Eddie

Please login to reply.