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

How to conditional include files in Fortran code

Zhanghong_T_
Novice
4,360 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,360 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,360 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,360 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,360 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,360 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,360 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,360 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,360 Views
Dear John,

I tried as you suggested, still failed.

Thanks,
Zhanghong Tang
0 Kudos
jimdempseyatthecove
Honored Contributor III
4,360 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,360 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,360 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,360 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,360 Views
How does it fail? Can you attach a ZIP of a project that has the problem?
0 Kudos
Zhanghong_T_
Novice
4,360 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,360 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,360 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,360 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,360 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