Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
29282 Discussions

How to conditional include files in Fortran code

Zhanghong_T_
Novice
4,518 Views
Dear all,

I need to include some files in a subroutine. The code in the subroutine is as follows:

INCLUDE 'header.h'
...


The header.h is as follows:
#ifdef WIN32
include 'header_32.h'
#else
include 'header_64.h'
#endif

However, the definitions in the file header_32.h or header_64.h can't be recognized by the compiler, what should I change the code or change the settings of project? I am using VS2008 + IVF 11 for windows.


Thanks,
Zhanghong Tang
0 Kudos
18 Replies
Les_Neilson
Valued Contributor II
4,518 Views
The code in header.h as you have written it is for C
For Fortran you would write

!DEC$ IF DEFINED (WIN32)
include 'header_32.h'
!DEC$ ELSE
include 'header_64.h'
!DEC$ ENDIF

assuming the contents of the two include files are Fortran and not C

It is usual (though not compulsory) for C/C++ include files to have a '.h' extension and include files for Fortran to have an extension of '.fi' or '.ins' or '.inc'

Les
0 Kudos
Zhanghong_T_
Novice
4,518 Views
Dear Les,

Thank you very much for your kindly reply. I tried to change the header.h as you suggested but it is still not correct. In fact, if not include files, the program can be built as what I excepted, for example, the following code can be executed correct

#ifdef WIN32
block A
#else
block B
#endif


Thanks,
Zhanghong Tang
0 Kudos
jimdempseyatthecove
Honored Contributor III
4,518 Views
Tang,

The syntax

#include ...
#if ...
#ifdef
#else
#endif
#define

Are supported by the Fortran PreProcessor. These are not supported by Fortran.
If you want or need to use #... format, then you must also include the compiler directive to use the Fortran PreProcessor enabled with /Qfpp switch. There are additional preprocessor options that you might want to look at (use 'ifort /help")

The !DEC$ ... format as Les illustrated are Intel Fortran supported conditional compilation directives.

Jim Dempsey
0 Kudos
Les_Neilson
Valued Contributor II
4,518 Views
Thanks Jim for the clarification. I have never used the preoprocessor form of the directives but sure enough, in the help under "preprocessor"there they are.
Even after all this time I'm still learning something new.
:-)

Les
0 Kudos
TimP
Honored Contributor III
4,518 Views
If you will use the CPP form
#include "yourincludefile"
and specify pre-processing in your Visual Studio properties or command line (/Qfpp), then CPP style pre-processing will be supported in yourincludefile.
CPP pre-processing is not a Fortran standard, and is done slightly differently by various compilers, the only known common denominator being the requirements of the OpenMP standard.
A commonly used alternative for pre-processing is to set up the build to invoke a C pre-processor or open source fpp explicitly, such as
gcc -E -traditional -x c yoursourcefile > yourpreprocessedfile
or (exactly the same effect)
gfortran -E yoursourcefile > yourpreprocessedfile
followed by
ifort yourpreprocessedfile
Taking care to give yourpreprocessedfile a name understood by ifort but not over-writing yoursourcefile.
Needless to say, Microsoft build style is at odds with this method.
0 Kudos
Zhanghong_T_
Novice
4,518 Views
Dear all,

Thank you very much for your kindly reply. I have already specified preprocessing in VS environment (/fpp). But as tim18 said, I still can't let the IVF compiler recognize the header if I build the project in VS+IVF, isn't it?


Thanks,
Zhanghong Tang
0 Kudos
John4
Valued Contributor I
4,518 Views

If the file you're trying to include also requires some preprocessing, you'll need "#include" instead of the corresponding Fortran statement, as in:

#if defined (WIN32)

#include 'header_32.h'

#else
#include 'header_64.h'
#endif


0 Kudos
Zhanghong_T_
Novice
4,518 Views
Dear John,

I tried as you suggested, still failed.

Thanks,
Zhanghong Tang
0 Kudos
jimdempseyatthecove
Honored Contributor III
4,518 Views
Tang,

One of the areas to look at is a descrepancy between Fortran INCLUDE and FPP #INCLUDE is that the Fortran INCLUDE is generally scoped within a subroutine or function whereas the FPP #INCLUDE is a blob of text inserted into your source file.


*** BAD USE ***

! souceFile.f90
subroutine A
real :: x,y,z
#include "foo.inc"
...
end subroutine A

subroutine B
real ::q,w,e,r,t,y
#include "foo.inc"
...
end subroutine B

-------------------------------
Where

foo.inc has

#ifndef _foo_inc
#define _foo_inc
...
#endif
-----------------

In the above sample, the blob of the include does not get expanded in the subroutine B
You have to be careful when trying to marry C style inlcudes within Fortran.

A second problem to work around is when the included file(s) contain #define
and when the included file is inlcude into multiple subroutines within the same source file.
You can use #include multiple times but you have to be aware of the consequences and knowledgeable of the work arounds.

Jim Dempsey


0 Kudos
Zhanghong_T_
Novice
4,518 Views
Dear Jim,

Thank you very much for your kindly reply. However, I just have this kind of requirement. I wish the code include different header files under different systems (but the original code can't be changed), as I know, it can be done in C++ compiler. Do you have any good suggestion, or it just can't be done like this?


Thanks,
Zhanghong Tang
0 Kudos
Steven_L_Intel1
Employee
4,518 Views
First, the predefined symbol name is _WIN32, not WIN32. Second, this symbol is defined for both 32 and 64-bit. Perhaps what you want is _M_X64 which is defined for a 64-bit build but not for a 32-bit build.

You could do it this way:

!DEC$ IF DEFINED(_M_X64)
INCLUDE '64bit.h'
!DEC$ ELSE
INCLUDE '32bit.h'
!DEC$ END IF

and not enabling preprocessing, or:

#ifdef _M_X64
#include '64bit.h'
#else
#include '32bit.h'
#endif

with preprocessing enabled.

My preference would be to do neither, if possible, and have a single INCLUDE file that is coded to "do the right thing" for a 64-bit system, based on definitions in ISO_C_BINDING.
0 Kudos
Zhanghong_T_
Novice
4,518 Views
Dear Steve,

Thank you very much for your kindly reply. I tried both methods suggested but still failed. In fact, I have defined the WIN32 or WIN64 in VS2008 project settings:
Project->Properities->Fortran->Preprocessor

Thanks,
Zhanghong Tang
0 Kudos
Steven_L_Intel1
Employee
4,518 Views
How does it fail? Can you attach a ZIP of a project that has the problem?
0 Kudos
Zhanghong_T_
Novice
4,518 Views
Hi Steve,

Thank you very much for your kindly reply. I have attached the project. Please help me to take a look at it.
Just now I noticed that maybe it is caused by .F file requiring start from 7th column at every line, so I let the words start from 7th column, the following error displayed:

error #6417: The dimensions of this array have been defined more than once. [TEST] header_64.h 1




Thanks,
Zhanghong Tang
0 Kudos
Les_Neilson
Valued Contributor II
4,518 Views
In the header.h from the zip file you have #!DEC$ -- I removed the #

The fortran file extension ".F" will mean that the file isfixed form

Thismeans that the contents ofall the include files will also need to be fixed form. (Unless you have a compiler directive in them saying otherwise, which you don't have in this example)

The project properties shows that WIN32 is defined as a preprocessor definition so the compiler will include the header_32.h file. (Your example project only has one configuration define - Win32)

As a start make the contents ofall of the include files fixed form (or make everything free form which would be better)

Les
0 Kudos
Zhanghong_T_
Novice
4,518 Views
Dear Les,

Thanks for pointing out this for me. I also noticed that and changed the include files to be fixed format but another error displayed:
error #6417: The dimensions of this array have been defined more than once. [TEST] header_64.h 1


Thanks,
Zhanghong Tang
0 Kudos
Steven_L_Intel1
Employee
4,518 Views
When I make the changes Les suggests, I get no error. Please attach a new ZIP showing the files as you have them now.
0 Kudos
Zhanghong_T_
Novice
4,518 Views
Hi Les and Steven,

Thank you very much for your kindly help. I checked and found that I have a mistake in the header.h and after I changed it no error appears.

Thanks,
Zhanghong Tang
0 Kudos
Reply