You should note that lfortran is still very much under development and it may be that the old construct âINCLUDEâ is not supported. You may have better luck by either using a different compiler like gfortran or ifx, which do support the FORTRAN 77 style construct you have encountered or turning the include file into a module.
I think @Arjen already gave you the most probable reason why âINCLUDEâ doesnât seem to work (LFortranâs support of some older features is not yet on the same level of maturity as that of the more recent Fortran features).
You may wish to try substituting INCLUDE 'XFOIL.INC' by #include "XFOIL.INC", though, since LFortran does support C-style preprocessing with the --cpp compiler flag.
We support include, but didnât support it in fixed-form, which I now fixed.
We now support all Fortran features (except coarrays and length PDT), but they can still have bugs like the one you encountered. Modern Fortran in free-form works pretty well, some old F77 features might not be implemented yet (if so, please report it), also the fixed-form parser sometimes has bugs, but if you report them (ideally as a standalone minimal reproducible example), then weâll fix them quickly. Regarding compiling third-party codes, right now our status is expressed in the version information you printed above (Status: alpha (expected to fail on third-party codes)). So expected to fail, but it might not be difficult to fix all bugs to get it working, depending on the code. If you are interested, please report all bugs and weâll fix them all.
Some of these comments are a little confusing. INCLUDE was not an f77 feature. It was an extension of many f77 compilers, but it was not a standard feature. INCLUDE was part of f90, and remains standard even now with f2023 (in section 6.4).
Yes. Thatâs why we only supported it in free-form, because F77 codes in fixed-form wouldnât use it as much, but clearly they do. Anyway, itâs fixed in the latest LFortran main.
I would suspect just the opposite - that INCLUDE is used far more in older codes than more modern ones where modules are used.
Although not in the Fortran Standard until Fortran-90, INCLUDE has been around in one form or another long before that. Sometimes via pre-processing tools, and sometimes built into the compiler. It was also part of the DOD MIL-SPEC 1753 standard, published in 1978.
Thats my experience. Back in the days when COMMON blocks were the only way to share data globally, it was standard practice in just about every code I used from around 1983 on to place COMMON block definitions in INCLUDE files. That was about the only way in a very large code you could make sure that the COMMON blocks were defined consistently in every routine that used them.
I had always avoided using INCLUDE in f77 codes because I knew some compilers did not support it, and I wanted my codes to be as portable as possbile. I first saw INCLUDE used in fortran codes in the late 1970s. That would have been about the same time as the MIL-SPEC-1753 document, or maybe just a year or so before. So now Iâm curious, which fortran compilers supported INCLUDE before that? How about the DEC compilers in the late 60s or early 70s? Anyone know?
As for how it was used at that time, there were several situations:
It was a way to localize the IMPLICIT statements. Often there was a single âimplicit.incâ file that was included in the first line of each subroutine. This made it easier to change a whole program from REAL to DOUBLE PRECISION. With this convention, arrays were declared with DIMENSION statements and not with REAL, INTEGER, etc. statements, their types were determined implicitly from their first letter. Some compilers had default 16-bit integers, so this was a way to easily use 32-bit integers instead.
As already mentioned, it was a way to make common blocks uniform across a whole program. You could make a single change to a common block in the âcommon.incâ file, recompile, and everything was consistent. Well, mostly. You still had the issue of a common block variable clashing with a local variable.
For commonly used statement functions. Some compilers treated statement functions as in-line macros, so they were faster than using compiled external functions. But you needed a way to make them consistent across a whole program, so INCLUDE files could do that. The problem was to avoid multiple definitions of the various arguments.
If your program had shared parameters, e.g. integers used as array dimensions or real values of PI, speed of light C, and so on, then INCLUDE was a way to put them all in one place.
Common subprogram code for multiple types. If a REAL function, a DOUBLE PRECISION function, and a COMPLEX function all had the same statements, and differed only in the declarations of the variables, then INCLUDE could be used to simplify the code maintenance for that family of functions.
I would say that MODULEs in f90 mostly obviated the first four uses of INCLUDE, The last one was still used even with modules after f90. In fact, INCLUDE might have been used even more after f90 when generic subprogram interfaces were introduced and when multiple REAL, INTEGER, and LOGICAL kinds were standardized.
Nowadays for #5, I generally just use the fypp pre-processor. I keep going back and forth as to whether it is better to use macros (#:def), or loops (#:for) to replicate code.
In the early 2000s, I used the filepp preprocessor for that same purpose. It was written in perl, so it was portable and it gave the same behavior everywhere, unlike many of the fortran built-in preprocessors at that time. It started off as just a portable cpp replacement, but then some other features, such as loops and regular expression substitutions, were added. I experimented a little with writing library codes that supported multiple kinds using those features, but it was complicated.