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

Understanding of Common block and how it is used

mechprog
Beginner
2,898 Views
Hello all,

I am just trying to fully understand the physical meaning of code such as:

common/example/Wear(lines, 50)

Does this mean that
1) Common is used as a temp place to hold values
2) example is the name of common block
3) Wear is the argument which is an array with lines, 50 (i.e. matrix with "lines" (rows) by "50" columns

Thanks
0 Kudos
11 Replies
GVautier
New Contributor III
2,898 Views
Hello

For me, fortran common block can be understood as C global variables that can be shared between procedures.
0 Kudos
Arjen_Markus
Honored Contributor II
2,898 Views
A COMMON block as in the fragment above is an old way of reserving memory that can be
accessed in any subroutine or other program units that include such a declaration. This way
you can make data available in these units.

The rules for COMMON blocks allow a great deal of freedom, but in general:
- Make sure you use the same COMMON block declaration anywhere in the program
(If you do not, you are on your own). This includes: names, types, ordering
- Best way to guarantee the above: use INCLUDE
- (In new code) do not use them, use module variables instead

In your fragment, /example/ is the name of the COMMON block indeed and "wear" is the
name of a two-dimensional array.

Regards,

Arjen
0 Kudos
mechprog
Beginner
2,898 Views
Ok thanks,

I want to see exactly what my code is doing and calculating, I know I can use the following command to print out theFortan subroutine whilst it is in action by using

[fxfortran]write (7,*) "number is ' Number[/fxfortran]

But how do I print out arrays?

e.g.

[fxfortran]      Wear(ind,step)=Wear(i,step)-(X*Y*Z)
      inc(ind) =inc(ind)-(X*Y*Z)[/fxfortran]

As I do not fully understand the calculations it is doing and how it looks. Thanks.
0 Kudos
mecej4
Honored Contributor III
2,898 Views
You can print array variables by just including the array name in the I/O list, e.g.,

write(*,*) inc, Wear

However, it is common in older Fortran programs to have the declared size of arrays to be greater than the portion in use in a specific calculation. Here the use of array expressions as subscripts or implied DO loops is indicated.

You should probably work through a Fortran tutorial and consult textbooks and language manuals if these concepts are unfamiliar to you.
0 Kudos
mechprog
Beginner
2,898 Views

In fortran is there any way of commenting out multiply lines of code without having to put a "C" at the beginning of every line? If I have over 100 lines to comment out (during debugging), then it takes a while.

Thanks.

0 Kudos
Arjen_Markus
Honored Contributor II
2,898 Views
No, there is no "block comment".

A possible workaround is:

if ( .false. ) then
... put the code that you do not want to execute here
endif

(In fixed form there is a non-standard feature to put a "D" instead of a "C"
in the first column - such lines are only treated as valid code when you ask
the compiler nicely to include them, but I find that practice highly confusing.)

Regards,

Arjen
0 Kudos
jimdempseyatthecove
Honored Contributor III
2,898 Views
You can use compiler directives

Fixed form:

cDEC$ IF(.false.)
...
cDEC$ ENDIF

Free form:

!DEC$ IF(.false.)
...
!DEC$ ENDIF

RE: COMMON blocks

If you are a C/C++ programmer, named common blocks are equivilent to C/C++ named static UNIONS of structs. Example

Source 1
COMMON /FOO/ A, B, C, I

Source 2
COMMON /FOO/ A, B, C, D,I

Is somewhat equivilent to C/C++

union
{
struct { float A; float B; float C; int I; } Source1;
struct { float A; float B; float C; float D; int I; } Source2;
} FOO;

And where use of I in Source 1 is equivilent to C's FOO.Source1.I
*** Note that this mapps to the same addres as FOO.Source2.D ***

An alternate view point is through use of void*

entern void* FOO;
Then Source1 uses a cast on FOO to a source 1 delcared struct produce the mapping, whereas source 2 declaring a different struct to produce a different mapping.

Therefore, as recommended earlier: Use INCLUDE's to define your COMMON's (IOW use but one source file for mapping out the commons. Then assure both (all) sources accessing the COMMON/FOO/ uses the same INCLUDE file.

Jim Dempsey
0 Kudos
mechprog
Beginner
2,898 Views

Thanks, but this does not seem to work, perhaps it does not work if there are any comments placed between the if and endif commands?

0 Kudos
GVautier
New Contributor III
2,898 Views

I use to complete the includes for common blocks with the definition for each common block of a structure embedding all variables. This practice avoid the non intentional use of a common variable in a procedure and ease the evolution of common block during the development process:

Replacing
COMMON /FOO/ A, B, C, I

by

type common_foo_type
... A,B,C,I
end type

type (common_foo_type) cf

common /foo/cf

and accessing the variables with cf%a ...

0 Kudos
Les_Neilson
Valued Contributor II
2,898 Views

Either of the techniques proposed by arjenand jim will "work". There is no restriction on what lies between the if and the endif.

If you are using Visual Studio there is a method of commenting blocks of code whereby you hightlight the code you wish to comment out and do ctrl-K ctrl-C.
To undo the comments highlight the code and do ctrl-K ctrl-U

Les

0 Kudos
bmchenry
New Contributor II
2,898 Views

you also might try to simply replace the common with a module
module FOO
implicit none
Real A,B,C
end module

then simply insert a
USE FOO
into any subroutine that needsaccess to the 'common stroage' and A,B,C are available

One other item to consider:
In older programs COMMON storage was considered sequential so if there are any equivalences in your code, you need to determine if they used specific parts of arrays for different variable.
you can still mimic that behavior with a Module and equivalence command, just need to be sure you are handling memory as expected for the older code.

0 Kudos
Reply