Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28701 Discussions

Best way to set up "once only" code ?

WSinc
New Contributor I
703 Views

I have a subroutine where I only want to execute a block of statements the FIRST time it's called.

I tried to do it this way:

INTEGER  Once

DATA once/0/

IF(ONCE == 0)THEN

!  EXECUTES A BLOCK OF STATEMENTS

 

...

...

...

ONCE =1

ENDIF

For some reason, the compiler set it to Zero every time it was called.

How do I tell the compiler that an item is NOT supposed to be reinitialized every time?

I am not sure that the standard really addresses this issue.

0 Kudos
12 Replies
Paul_Curtis
Valued Contributor I
701 Views

Give your flag the SAVE attribute.
 

0 Kudos
Steven_L_Intel1
Employee
701 Views

The DATA statement implies SAVE. I would want to see an actual example that demonstrates the problem. My guess is that Bill is inadvertently leaving something out of his paraphrase.

0 Kudos
Jacob_Williams
New Contributor II
701 Views

The following works.  Plus, it avoids DATA, which I must admit I've never used or understood.
[fortran]
    logical,save :: initialized = .false.
    
    if (.not. initialized) then
    
        !EXECUTES A BLOCK OF STATEMENTS
        !...
        
        initialized = .true.
        
    end if
 [/fortran]

0 Kudos
Steven_L_Intel1
Employee
701 Views

Jacob, your code is essentially the same as if DATA was used. Semantically, they are identical.

0 Kudos
Paul_Curtis
Valued Contributor I
701 Views

I'm with Jacob, I use his exact approach often, never a problem (and I too do not use DATA initialization).

From the IVF documentation : "...a named variable has the SAVE attribute if any part of it is initialized in a DATA statement. You can confirm this property by specifying the variable in a SAVE statement or a type declaration statement containing the SAVE attribute"

Perhaps it is actually necessary (and not redundant) to explicitly "confirm" the SAVE attribute.

 

0 Kudos
Steven_L_Intel1
Employee
701 Views

It is redundant to specify SAVE for variables given initial values either through DATA or an initializer. This wasn't the case in F90, but as of F95 it is.

0 Kudos
jimdempseyatthecove
Honored Contributor III
701 Views

If you have a small routine that is heavily executed, then might be (performance wise) a good opportunity to consider GOTO to goto (out of line) to the bottom of the program, perform the initialization, then goto back to following the IF statement. If the initialization code is close enough, then this may eliminate a branch in your code, and shave a few clock ticks off each call. You would have to inspect the code generated, because program optimization undo what you were trying to do.

Jim Dempsey

 

0 Kudos
Jacob_Williams
New Contributor II
701 Views

I like to include the "save" even though it is redundant.  Partially as a reminder to myself.  Also: I tend to avoid using saved variables, so if I'm using one somewhere, I want to make it easy to locate if I need it find it again one day.  It doesn't hurt, right?

0 Kudos
WSinc
New Contributor I
701 Views

I take it that the DATA statement is considered to be obsolete ?

Or just old-fashioned ?

0 Kudos
IanH
Honored Contributor III
700 Views

Both :)

(but not formally)

0 Kudos
Steven_L_Intel1
Employee
700 Views

Old-fashioned, maybe. There are things you can do in DATA that are not easily done with initializers, regarding arrays. Use whichever one you prefer. Personally I like keeping things together, so I use initializers where I can. Spreading a variable's information over multiple statements can lead to errors.

0 Kudos
John_Campbell
New Contributor II
700 Views

Bill,

I use the approach you are adopting in many applications and it works for me.

I'd suggest that you include a write (*,*) 'once =',once at the start and end of the routine and see what is happening. Make sure you put it at the end ! You might be using once elsewhere.
Is once= 1 being executed or is there a return somewhere in that code ?

John

0 Kudos
Reply