I had a Fortran module file (filename.F), which contains a line of statement:
#include "module_io_domain_defs.inc"
which I don't quite understand. Why is a "#" symbol. Should not be just
include "module_io_domain_defs.inc"
I know during the compilation process, the *.F file becomes *.f90 file. How to understand the above statement and how dose the compilation process work?
The # designates a C preprocessor directive. Therefore the #include is not processed by the Fortran compiler but by a C preprocessr (cpp, c-preprocessor). The capital .F instead of f typically tells the compiler to run cpp before compiling.
The main difference is that the file included by #include will again be processed by cpp, whereas a file included just by include will not be processed by anything before compiling.
The preprocessor can also be requested by passing a flag such as -cpp or -fpp if the compiler does not recognize the capital F in the suffix.
Related
Suppose I have a file test.f90 (free-form code) that includes some other file foo.h (fixed code).
The two didn't work well together because they have different comment styles, so I put a preprocessor directive !DIR$ NOFREEFORM at the top of the foo.h source code, which tells Intel's Fortran Compiler ifort to interpret that file as fixed-form source code.
Unfortunately, the rest of my code in test.f90 gets errors that indicate ifort is interpreting it as fixed-form rather than free-form code.
I haven't rigorously checked, but is it possible that the preprocessor directive in foo.h is causing ifort to interpret the code in test.f90 as fixed-form? I didn't think this was possible because ifort treats each included file as a separate compilation, rather than just copy-pasting the code.
The latest standard states
The effect of the INCLUDE line is as if the referenced source text
physically replaced the INCLUDE line prior to program processing.
so it is entirely possible, in fact absolutely inevitable, that the preprocessor directive in the included file causes the compiler to change its interpretation of the code.
include-d files are not separate compilation units.
I guess you should be able to use!DEC$ FREEFORM to switch the compiler's behaviour back again.
I have a "Common.h" file, which stores all the strings are reused across my project.
namespace Common{
static const std::string mystring = "IamAwesum";
}
So in any file that needs a particular string I include the file:
include "Common.h"
and then where I need the string I use:
Common::mystring
Now I noticed in Xcode, that none of the ".h" files are included in the target. But it seems my program works fine as expected. Can someone explain what happens to .h files? How does this work ? Is it because the file that "includes" "Common.h" has a copy of all the data ?
A header is not compiled (exceptions being pre-compiled headers, a common build optimization technique, and by mistake), but is instead, as OP suspected, copied into the files which use them.
From [cpp.include] in the C++ Standard
A preprocessing directive of the form
# include " q-char-sequence" new-line
causes the replacement of that directive by the entire contents of the source file identified by the specified sequence between the " delimiters.
The included file is pasted into the file being compiled where the #include directive is, replacing the #include.
So if a file is not included, it never gets substituted into a file being compiled and absolutely nothing happens to the file.
An included file doesn't need to be listed anywhere in a project, target makefile, or what-have-you. The inclusion of the file is strictly up to the cpp file doing the including, though often a list of places to look for included headers will be present to abstract away the toolchain and libraries from the source code.
I am trying to include a file 'a.h' into a Fortran program 'b.f'
The contents of the files are as follows:
a.h
c This is a comment
k = 10
100 format( I5 )
b.f
program test_include
include 'a.h'
write(*,100) k
end program test_include
When I try to compile the file 'b.f' using the following command
gfortran -ffree-form b.f
The compiler gives the error
Included at b.f:2:
c This is a comment
1
Error: Unclassifiable statement at (1)
But when I change the comment line to
!c This is a comment
gfortran compiles it successfully and the program runs correctly.
Can someone tell me how to make gfortran recognize lines beginning with 'c' in a '*.h' file as a comment. I am trying to include a similar file (with comments beginning with 'c') from a library into my free-form fortran code, and I can't really make all the comments beginning with 'c' in that file, to begin with '!'.
The include file is in fixed-form! You cannot mix free and fixed form in a single file. Since
[the] effect of the INCLUDE line is as if the referenced source text physically replaced the INCLUDE line priorto program processing [,]
the combined source text needs to be either fixed or free form, but not a mixture of both.
[Source: Fortran 2008 Standard, Cl. 3.4 (6)]
This leaves you two options:
Convert the main program to fixed form, or
Convert the include files to free form.
For 1), you need to specify -ffixed-form, and format b.f to comply to fixed form. b.f would then look like
program test_include
include 'a.h'
write(*,100) k
end program test_include
For 2) , you would convert the include files to free form. The include could then be written as:
! This is a comment
k = 10
100 format( I5 )
If you cannot convert all files, I would suggest writing wrapper modules in fixed-form, include the source code, and from then on use the wrapper modules instead. In case of the snippet you provided, this would require further thought, but in case of include files with only variables/parameters/interfaces this could look like
module wrapper_vars
include 'vars.h'
end module
For subroutines and functions, you could also use modules:
module wrapper_subroutines
contains
include 'subroutines.h'
end module
I am using some F77 fixed format code with my F90 program. I am trying to include both kinds of code in my main program. Here's how I have arranged my code:
Header files:
File Name:include.inc
include 'module_variables.F90'
include 'message.F90'
include 'module_common_functions.f90'
include 'module_input_gdf.F90'
...
Relavant LAPACK files
File Name: lapack.inc
include 'xerbla.f'
include 'strsm.f'
include 'slaswp.f'
include 'sgetrs.f'
include 'sgetrf.f'
...
Now my main program looks like:
include 'lapack.inc'
include 'include.inc'
program MDL_HydroD
use module_variables
use module_write_files
use module_read_files
...
When I try to compile my main code with ifort "MDL HydroD.F90", the F77 formatted files give error message:
xerbla.f(1): error #5078: Unrecognized token '\' skipped
*> \brief \b XERBLA
---^
This is because the compiler is reading the commented section (starts with *). Is there any way I can compile with both type of fortran code in my header.
Note: I am using Intel Composer XE 2013 with command prompt.
There are compiler specific directives (not part of the standard language), for that compiler, that allow you to change the source form in use.
Place the relevant directive before the include file, and then place the other directive after the include file to switch the source form back. Perhaps:
!DEC$ NOFREEFORM
INCLUDE 'lapack.inc'
!DEC$ FREEFORM
See http://software.intel.com/en-us/node/466230 for more information.
Do we have any option in gcc to find from where a particular file header is included.
I have the following scenario :
file_1.h :
declare type of type_1
file_2.h :
type_1 var;
I want to check where was file_1.h included in the library that i am creating.
gcc has an option -M:
-M Instead of outputting the result of preprocessing, output a
rule suitable for make describing the dependencies of the main source
file. The preprocessor outputs one
make rule containing the object file name for that source file, a colon, and the names of all the included files, including those
coming from -include or -imacros
command line options.
If you do, gcc -M filename.c, it'll list out all headers. Same with g++.
If you look at the preprocessed output it will show the headers that were included, in the order they were included, so you can see where file_1.h appears and work backwards to see which file included it, and which file included that etc.
The -E option tells GCC to only perform the preprocessing step and to stop before compilation.