Directives in Included files in Fortran - fortran

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.

Related

C++ precompiled-headers huge in size

I have 2 questions about c++ precompiled-headers feature.
1.What actually is happening when you make a .gch file (using GCC), what it contains ?
2.Why those files are so huge in size , but the final executable is so small.
When you precompile a header, it all begins like an usual compilation:
The preprocessor is run, including any dependent headers and performing macro substitution
The resulting source code is hander over to the compiler, which parses it and validates the syntax
Then the compiler produces the AST, the data structure which encodes the semantics of the code
Usually, this is done on .cpp files, and goes on afterwards to actually compile the AST and generate executable code. However, a header precompilation stops there, and the compiler dumps the AST inside the .gch file.
On further uses of this precompiled header, the compiler can then directly load the AST back from file and pick it up from there, skipping the costly processing listed above.
The .gch file is huge, because it contains a lot of information that was implicit in the original header. But it has no relation to the size of the final executable -- compiling with and without precompiled headers should produce the exact same result.

#include <iostream> in C++?

I read that #include <file> will copy paste “file” into our source file by C++ preprocessor before being compiled.
Does this mean that the “file” (iostream) will also be compiled again and again as long as we compile source file?
Also after C++ does its job, will the size of intermediate file also have bytes of “file” + "size of source file"?
I read that #include <file> will copy
paste “file” into our source file by C++ preprocessor before being
compiled.
Yes. The data that the compiler proper sees will consist of the data in file and the data in your source file. (Actually, real compilers these days tend to merge the C preprocessor and the compiler front end and the compiler back end into a single program - but that is pretty much a detail.)
Does this mean that the “file” (iostream) will also be compiled again
and again as long as we compile source file?
Yes. Some compilers have a feature called "pre-compiled headers" which allow you to compile a bunch of headers once, and then use the output of that multiple times. How you do this varies from compiler to compiler; if you need portability, don't worry about it (it doesn't make that big a difference to compile times).
Also after C++ does its job, will the size of intermediate file also
have bytes of “file” + "size of source file"?
No. The size of the output file is only very weakly related to the size of the source file. For example #include <iostream> defines many, many inline functions. Any particular program will only use a very few of those - so they will be omitted from the compiler output.
Comments (which use space in the source file) don't appear in the output.
On the other hand, if you write a complex template, and then instantiate it for several different types, then the output will contain a different copy of the template for each type, and may be quite a bit larger than the input.
Regarding the size of intermediate file size, yes it will increase. You can check this by writing a simple hello world program and then compile it as follows (in Linux)
g++ name.cpp -o name --save-temps
This will store intermediate files, specifically:
"name.ii" (Preprocessed code after including <iostream>
"name.s" (Assembly version of the code)
"name.o" (Object code)
Check the difference in this size of file using:
ls -l name.cpp name.ii
No.libraries(headers) don't increase the size of file because compiler don't add all of the header into your code.It just add things you use in your code to your code,
No, it doesn't increase program size. The file iostream and many other header files don't have compilable statements. They contain some definitions required for you program.
If you look at a preprocessed C/C++ file, you will see thousands of definitions are added at the beginning of the file.
You can try it with cpp tool, run it with commands just like normal g++/gcc and see the outputs.
cpp -I /usr/include/ -I. file.cpp -o file.preprocessed
It contains just the headers and definitions, they don't increase you final program size.
Edit:
As martin said, they have compilable inline functions which will compile each time, but they doesn't increase your program size unless you use them.
I read that #include <file> will copy paste “file” into our source
file by C++ preprocessor before being compiled.
It's a little more subtle than that. #include "file" does what you describe. #include <file> pulls in a header which is not required to be a file. The idea is that the compiler can have its own internal version of that header, already in binary form, so it doesn't have to read and parse a file. If there is no header with that name, then it treats the include directive as if it had been #include "file" and looks for a file to read.
In practice, I don't know of a compiler that takes advantage of this leeway; all headers are, in fact, files that get compiled over and over again. But, as others have said, that in itself does not mean that the executable file becomes larger. Ideally, if you don't use it, it doesn't get into the executable, although some systems are better about this than others.

How precompiled headers actually works

All my quetions are related to vc++ compiler but I guess other c++ compilers have the same behavior.
Are the precompiled headers a preprocessor-related stuff or this is all about the compilation process? Or both? I have several guess:
PCH-engine only expands MACRO-definitions and nested headers and translates them into binary format (pch file). In this case all source-files (I mean cpp/hpp which may be included in PCH too) will being recompiled in EVERY source files in project. Or not?
All source-files will be compiled only once and pulled into single obj-file? For example, how many times will be compiled variant library in this example? I.e. only once - in PCH or two times - not in PCH but in both *.cpp files or three times - in PCH and both *.cpp files? and why?
//stdafx.h
#include <boost/variant/variant.hpp>
//test1.cpp
#include "stdafx.h"
#include <boost/variant/variant.hpp>
...
//test2.cpp
#include "stdafx.h"
...
What files should I put in precompiled headers? I guess this is something that used everywhere in project and changed very rarely. What about libraries, boost for example? We use boost only in few source-files, should we put it in PCH?
I have no particular knowledge of VC++'s innards. However, having some knowledge of compiler design and theory, what these so-called "precompiled headers" are can't be anything more than just the result of the initial lexical analysis and tokenization phases of a classical compiler design.
Consider a simple header file that contains the following:
#ifdef FOO
#define BAR 10
#else
#undef FOOBAR
class Foo {
public:
void bar();
};
#include "foobar.h"
#endif
You have to understand that the effect of using a so-called "pre-compiled" header must be identical to using the header file, as is.
Here, you don't really know what this header file is going to do. It all depends on what preprocessor macros are defined when the header file is actually included. You don't know which macros this header file will define. You don't know which macros this header file will undefine. You don't know what other header files this header file will include. You don't really know a lot, here.
The only thing you can conceptually do, to "precompile" a header file, is to pre-parse it. Convert the individual elements of the language, the individual keywords -- like "#ifdef", "class", and all others, into individual binary tokens. Remove any comments, whitespace, etc...
The first phase of compiling a traditional language involves parsing the plain text source into the internal language elements. The lexical analysis and the tokenization phase. After the individual language elements get parsed, then an attempt is made to figure out how the resulting, parsed source code, should get turned into an object module. And that's where 99% of the compiler's work is. The initial lexical analysis phase is not really a lot, but that's pretty much all you can do to "precompile" the source code, and save the internal binary representation of the tokenized source, so that this phase can be skipped, when actual code that uses the "precompiled" source is compiled.
I am assuming that VC++ places little, if no restrictions at all, on the contents of precompiled headers. However, if there are some restrictions -- say, the precompiled headers cannot have any conditional preprocessor directives (ifdef/ifndef) except for the classical guards -- than it would be possible to do more work to produce the precompiled headers, and save a little bit more work, here. Other restrictions on the contents of precompiled headers could also result in some additional functionality being shifted into the precompilation phase.
The precompiled header file, which gets compiled due to stdafx.cpp is stdafx.h. A developer would put rarely changed, and frequently needed header files and symbols in this header. Such as Windows.h, vector and some global macros and symbols. By frequently used, I mean across all files in given project.
What's the purpose and helpfulness of such file (PCH)? Well, VC++ compiler will compile entire stdafx.h file, recursively, all headers included all macros and other symbols. For first time, it will take a lot of time, and will produce a PCH file (hence pre-compiled header). On subsequent builds, the elements included through stdafx.h will not be recompiled (as they are already in some binary/pre-compiled format). This reduces build time, and it would vary depending how many elements (headers, symbols etc.) are put through stdafx.h file.
If you have a large codebase, and less of elements in stdafx, you wont get advantage (for example, including common Windows and STL headers everywhere, having externs and typedefs everywhere). Better you find those elements, and put them into stdafx.h, and remove them from header/CPP files. This will greatly reduce overall build times.
This is where you can change it:
I think that MSVC looks for <application_name>.pch for the sole precompiled header for the translation unit and uses that instead of the transcluded header included under #line 1 "c:\\application_name\\stdafx.h" in the preprocessed .i file, if it is available. The precompiled header is probably a serialised AST i.e. the header has been lexed and parsed into an AST representation. It then does not need to lex (or parse) this region of the preprocessed output and just uses the .pch, which contains the lex+parse output of what is written in the preprocessor output under stdafx.h. The preprocessor has already done all other work on stafx.h, such as expanding macros (which don't appear in the .i file / preprocessor output).

Can i compile a c++ file within a c++ file execution without any extra programs or installations?

I was reading on Clang and Ch (c++ interpreters), but its not clear for me, is it possible to run a newly generated .cpp file without any installations? Because i need to run the final program on any pc...
ps. if yes, does anyone have a good example, where a .cpp file is being executed within c++ code?
This is probably impossible or at least very hard. You would have to include the whole compiler (including linker, assembler, optimizer, preprocessor, ...) inside your program and that would make it extremely big.
One way of doing this is with Clang (as you already noted), there is even a demo project called "Clang interpreter" in the source: http://llvm.org/viewvc/llvm-project/cfe/trunk/examples/clang-interpreter/
However I once tried to compile this "beast" into my program and gave up halfway, because the file size of the result binary (or binaries with external libraries) gets into tens of megabytes (maybe even a hundred).
My suggestion is to either produce a different script (e.g. bash/sh script, which you could execute on any unix machine) that can be interpreted easily.
As far as I know, it is impossible, because compilation process of a CPP file is like this-
Preprocessing: the preprocessor takes a C++ source code file and deals with the #includes, #defines and other preprocessor directives. The output of this step is a "pure" C++ file without pre-processor directives.
Compilation: the compiler takes the pre-processor's output and produces an object file from it.
Linking: the linker takes the object files produced by the compiler and produces either a library or an executable file.
So, there should be intermediate files and executable files.
More can be found here-
https://stackoverflow.com/a/6264256/7725220
Kind of depends on what you mean by "installations".
Yes you can distribute your program with a full compiler, compile the source code and then execute the final result (all from the original exe).

Very Simple Question on Fortran - UNIX Compiling

Apologies if this is too naive or obvious but after a fair bit of searching around, I'm not 100% sure that I understand the fortran/unix interface. My uncertainty is regarding the nature of .src, .f, then .o, and .out files that you run into when compiling fortran programs into a unix executable. It's tough to google file extensions like this. But if you could tell me if I've got this straight, I'd really appreciate it!
.src is the source file which contains the meaty fortran code
.f is the 'host-language specific include file' that tells your fortran compiler a little bit about the source code. It's sometimes interactive.
--- After you've obtained .o or .out files, can throw away the .src and .f files, yeah?
.o is the binary object file that results from compiling but not linking the fortran .f and .src files. It contains the same meat but now converted into machine-specific instructions?
.out is the linked object file(s) which is executable and remains dependent on the .o file(s) and is machine-specific. The .out file extension is not really needed and is often omitted?
I think that covers it. Thanks for any corrects or further descriptions.
Kyle
Nothing about these file extensions is set in stone; as you said, they can even be omitted, or you can make up your own. However, it makes life far easier if you use the conventional ones.
I've never seen the .src extension. The directory where the source files are located is often referred to as ./src; maybe you've seen this.
Usually, the source code (plain text) is in a file with extension .f or .f90. The first one indicates fixed source form ("old style"), and the second one free source form ("modern"). Some compilers interpret uppercase file extensions (.F and .F90) as an indication that the source has to be run through the preprocessor first. Instead of letting the compiler use the extensions for these interpretations, all this can also be explicitly stated/overruled by passing flags to the compiler.
Compilation of the source code produces object code (the machine-specific instructions you mention), contained in an object file, usually with .o as extension (sometimes .obj, or other).
After creating the object files, you could indeed throw away your source code files, but you don't want to do that. You want to fix any bugs you most likely made, and also keep them for future alterations to your program.
The object code has to be linked to produce the final executable. If you have more than one object file, they are tied together, with inclusion of any system/external library code you referred to. On Unix, if you don't specify a name for the executable, the default name it gets is usually a.out. Again, you can overrule this by passing an argument to the compiler.
No, the Fortran code is usually in .f or .f90 files. In more detail, Fortran source code usually has the extension .f if it uses the fixed source form (the standard source form of Fortran 77 and earlier versions) or .f90 it uses free source form (present from Fortran 90 on).
After you've obtained .o or .out files, can throw away the .src and .f files, yeah?
No. As an addendum to the answers describing the various suffix conventions, I advise that you don't delete the Fortran source files (the .src or .f files in your description). You'll need these files if you ever want to modify the program, or if you need to investigate and fix errors you notice from running the executable file (a.out).