- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
test.F90
b.inc
test/
├─ a.inc
└─ b.inc
With the following contents:
- `test.F90`:
#include "test/a.inc"
end
- `test/a.inc`:
#include "test/b.inc"
#include "b.inc"
#include "b.inc"
- `test/b.inc`:
print*,"Hello from test/b.inc"
- `b.inc`:
print*,"Hello from b.inc"
A similar example was already discussed here. Running the compiled code with the Intel compiler (ifort 2021.8.0 and ifx 2023.0.0 on Ubuntu 18.04.2 LTS) without any flags leads to the following output:
Hello from test/b.inc
Hello from test/b.inc
Hello from test/b.inc
After the first `#include "test/b.inc"` in `a.inc` the directory is "changed" to `test` for some reason and only `test/b.inc` is included in all consequent `#include` statements.
Is it the intended behavior of the preprocessor? Or is it a bug?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This fpp issue is fixed in the compiler versions released this week as part of 2024.0.
@V-T, please try the new compiler.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Does this mean that there are two different fpp's? (or that ifx internally processes #include?)
FWIW, this looks like a file caching issue whereby the file name.type alone is the key as opposed to the complete path.
Thanks for posting this, I will keep this in mind.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I didn't invoke fpp separately. It is the result of internal preprocessing by ifort and ifx.
I also don't think it is a file caching issue: the directory is literally "changed" to `test`. You can check it by adding a `test/c.inc` file and changing the last `#include "b.inc"` to `#include "c.inc"`.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
fpp isn't invoked seperately.
There is an option to the compiler to invoke fpp....
however, on Linux:
foo.F90 (uppercase F) implicitly adds the -fpp, whereas
foo.f90 does not.
On Windows, you must supply the fpp option.
In either case, ifort/ifx command will invoke fpp.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sorry, I didn't formulate the sentence correctly. I meant that I didn't use fpp on `test.F90` in the first step and use ifx on the resulting preprocessed code in the second step (which, I think, should lead to the same result as the `ifx -fpp test.F90` command).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>Sorry, I didn't formulate the sentence correctly. I meant that I didn't use fpp on `test.F90` in the first step
Maybe I did not state the clearly before.
With the upper case F on .F90, the compiler front end called fpp. So in a sense, by using .F90 (on Linux/Mac) as opposed to .f90, you told the compiler to preprocess the file with fpp.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No, everything is alright with your reply. I did understand you. I know that `ifx test.F90` and `ifx -fpp test.F90` is the same command (on Linux/Mac) due to uppercase `F` in the extension. I just wanted to clarify that I only used `ifx test.F90` instead of `fpp test.F90 > test.f90 && ifx test.f90`. I differentiated between this two commands because, in the case of the GNU compiler, the analogous commands `gfortran test.F90` and `cpp test.F90 > test.f90 && gfortran test.f90` can sometimes lead to different results. But it is not the case with the Intel compiler.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I tested this on Windows, with /fpp, and I reproduced the strange behavior.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jim the manual seems to disagree with you, I know not what is true however....
To quote:
ifort source.fpp
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
additionally the fpp manual discusses search folder rules but only refers to "filename" or <filename> it gives no clue about adding path to the name which in any case is going to be operating system dependant.
The standard Fortran include statement e.g.
include 'filename'
also does not discuss the use of path within filename but for me 'filename' should be any string that is a valid absolute or relative URL for the OS being used. Does this option have the same problem BTW?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No, the Fortran `include` command (without `#`) doesn't have this problem. But all paths should be made relative to `test.F90` , i.e. changed to `include "test/b.inc"`, and no preprocessor lines are allowed in the included files.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I would agree it would make sense to have the relative paths anchored to the source directory but I was just commenting that the manual is silent on this matter so the "correct" behaviour is not defined. I personally would say it is a bug but it is really down to Intel to comment.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
gfortran won't even compile it!
$ gfortran test.F90
test/a.inc:2:2:
2 | #include "b.inc"
| 1~~~~~~~~~~~
Fatal Error: test/b.inc: No such file or directory
compilation terminated.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, of course, because the traditional cpp (which is used by gfortran) in contrast to fpp searches for the following files relatively to the file from which `#inlcude` is invoked (here: relatively to `test/a.inc`, not to `test.F90`). That's why `#include "test/b.inc"` is wrong because there is no `test/test/b.inc` file and only `#include "b.inc"` can be used. It was already discussed on Stack Overflow (the link is in the question). Personally, I find the approach of cpp more preferable than that of fpp, because it allows more flexible structures of chained `#include` statements. But this behavior can be affected in the Intel compiler with the flag `-assume [no]source_include` (like Steve Lionel said).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No, I just tested it: `-assume [no]source_include` doesn't seem to affect anything in this example.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I filed a bug report, CMPLRLLVM-45307. I'll let you know when a fix is available.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
After discussion with the compiler team, we determined that the reproducer is working as expected. Preprocessor behavior is defined by the implementer; there is no standard at this time.
According to the Fortran Developer Guide and Reference, the compiler searches for include files in this order:
- In the directory of the source file that contains the include
- In the current working directory
- In the directories specified by compiler option I
- In the directory specified by compiler option -isystem (Linux* and macOS only)
- In the directories specified with environment variables CPATH (Linux* and macOS) or INCLUDE (Windows*)
- In the standard system directories
ifort/ifx will always include test/b.inc since we first search the directory of the source file that contains include and a.inc's directory is "/test".
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If I understand you correctly, the preprocessor should search for a `b.inc` file in the `test` directory first, because the `a.inc` file is in this directory. However, replacing the contents of the `a.inc` file with:
#include "b.inc"
#include "b.inc"
#include "b.inc"
will lead to the following output:
Hello from b.inc
Hello from test/b.inc
Hello from test/b.inc
But according to your reply, all printed messages should have been `Hello from test/b.inc`. After the first `#include` statement, the directory is changed to `test` for some reason, and I find this behavior inconsistent.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The compiler team is reevaluating with your new reproducer.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This fpp issue is fixed in the compiler versions released this week as part of 2024.0.
@V-T, please try the new compiler.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page