Maybe because at Intel, everything that is non-standard is (by consequence) non-intrinsic (to the Fortran Language Standard itself). And so, everything that is standard conformant (i.e. intrinsic to the Fortran Language), should be compatible with any standard conformant processor.
And indeed, feeding a unit including Intel ifport porting module, could not work if and only if using Intel processors.
Evidently, this is not the same thinking process among all processor vendors, causing the “intrinsic” program you report to compile with NAG processors and possibly fail with all the others not providing the same (vendor specific) functionality. Which to me, does not look right.
I’m not familiar enough with these modules to know whether the vendors provide the sources of them for consumption by other Fortran processors.
Judging by the Intel documentation page, they ship a library libifport.a and a .mod file, which will fail to work with other compilers. Even if the objects in the archive use the same calling conventions as other compilers, the difference in implementation of logicals is one potential issue that could prevent correct usage.
In principle one could attempt to write the module with the same behavior from the description of the routines, and observation of their behavior (i.e. clean-room design).
Intel provides sources for both intrinsic and non-intrinsic modules, but they generally contain only interfaces, they do not include definitions (implementations). Which intrinsically creates a dependency on the vendor specific distribution.
Sure. But circumventing things should not be the spirit when trying to resolve issues, IMO.
At least for Intel MKL, I believe I’ve used the modules together with other compilers like gfortran (but if I recall correctly a different archive file was provided). However I don’t have practical experience with other modules like ifport and ifposix. I can see the modules containing interface definitions are available in the /opt/intel/oneapi/compiler/latest/mac/compiler/include folder.
NAG appears to provide three modules at source level, but this is practically irrelevant, because they won’t have the intrinsic status if reused by other compilers (assuming you have the NAG compiler in the first place):
Intel Fortran conforms to the standard, from what I see:
C1404 (R1409) If module-nature is INTRINSIC, module-name shall be the name of an intrinsic module.
C1405 (R1409) If module-nature is NON_INTRINSIC, module-name shall be the name of a nonintrinsic module.
IFPORT is not the name of an intrinsic module per the standard, so constraint C1404 (per 23-007r1) is not met and the processor is right to detect and report this.
By the way, starting Fortran 2018, there is some good progress toward tightening up some of the aspects of both nonstandard intrinsic modules as well as nonstandard intrinsic procedures and the processors being required to have the capability to detect and report their usage (it may just be some compiler flag or whatever, but something shall be offered).
“Intrinsic” here means that it is recognized specially by the compiler. Consider intrinsic functions - many compilers provide intrinsic functions not mentioned by the standard. In the case of Intel’s ifport, it’s just an ordinary module the compiler finds by the same process it uses for user modules; it’s not intrinsic.
The purpose of USE, INTRINSIC is to prevent a user module from overriding an intrinsic module. Intel, for example, uses a different file type for the compiled intrinsic modules.
But that only applies up to the point where the developer of that compiler (also the standard Editor) has had the time to implement revisions from the standard.
From the NAG website, they have long ways to go to implement current standard (2018). Until they do, the compiler response cannot be seen as conformant by default, it needs study to check whether it is or not.
Oh yes, in principle it has been since Fortran 90 revision that first introduced MODULEs.
To reiterate a separate point re: your apparent motivation with this thread as you state in the original post with a string type: it’s best if such a type does not call for an USE statement a la CHARACTER type. Note intrinsic modules do require USE. For something as basic and crucial as strong, it’s best if it is truly an intrinsic type like CHARACTER.
Yes, that was intentional, just as non-standard intrinsic procedures are permissible, and the standard provides mechanisms for the user to say they want an intrinsic thing instead of a non-intrinsic thing, or vice-versa.
Regardless of the actual mechanism, the goal is generally to be able to distinguish between what external references are a standard part of the Fortran specification, a non-portable compiler-specific capability, or a third-party or in-house procedure.
When I see a USE statement it is useful to know if it is an intrinsic from the standard that is portable. If that is the primary meaning of USE,INTRINSIC then also allowing it to reference vendor-specific modules is confusing and it would have been better to have had three modifiers or to allow something like an additional STD option.
If the purpose is only to prevent you from calling anything else but what the compiler supplies or to be able to be sure you are not calling something supplied by the compiler then the function fits the current directive.
I have come to believe the intent is the second functional meaning and not the first more descriptive meaning that is more useful to someone reading the code.
So it is primarily useful to have the NON-INTRINSIC specification to prevent the use of compiler-supplied procedures where a name clash could easily exist if compiler vendors are free to create arbitrarily-named “intrinsic” modules (which it seems they are).
The INTRINSIC option is then left to mean to make sure the compiler-provided version is used, whether that is an intrinsic module or a vendor-specific one; and not an alternate provided by the user.
Think of it that way and it is simple. Think of the INTRINSIC keyword as meaning “standard-supplied” which is what I thought it meant when I first encountered it you will be found wrong
at some point.
So if the vendor is supplying something that can only be used with their compiler and not defining it as INTRINSIC I think they are defeating the basic functional meaning of the INTRINSIC and NON-INTRINSIC modifiers; but the way the standard description is written I can see how they might consider only modules supplied as part of the standard INTRINSIC.
So as others have mentioned, I think the Fortran standard is not restrictive enough in its definition to prevent suppliers from making up different meanings for its use.
The Fortran standard defines a set of intrinsic procedures and intrinsic modules, and allows a processor to extend this set with further procedures and modules. A program that uses an intrinsic procedure or module not defined by the standard is not standard-conforming. A program that uses an entity not defined by the standard from a module defined by the standard is not standard-conforming. Use of intrinsic procedures or modules not defined by the standard should be avoided. Processors are able to detect and report the use of intrinsic procedures or modules not defined by the standard.
I must say the paragraph is confusing…
The first sentence implies intrinsic modules are defined by the standard.
The second sentence says that using an intrinsic module not defined by the standard is not standard conforming, which would imply what NAG does goes against the standard.
The third sentence seems reasonable, standard modules should not define anything extra.
The fourth sentence recommends to avoid using non-standard intrinsic procedures or modules.
And the last sentence states processors should be able to report when a non-standard intrinsic procedure or module is used.
6.45.1 Applicability to language
The vulnerability specified in ISO/IEC 24772-1:2019 clause 6.45 applies to Fortran.
Fortran permits a processor to supply extra intrinsic procedures or extra intrinsic modules but requires
language processors to be able to diagnose their usage. The use of such intrinsics is not standard-conforming, even if the processor that provides them is standard-conforming.
6.45.2 Avoidance mechanisms for language users
Fortran software developers can avoid the vulnerability or mitigate its ill effects in the following ways. They can:
Use the avoidance mechanisms of ISO/IEC 24772-1:2019 clause 6.45.5;
Specify that a procedure has the intrinsic attribute in a scope where the intrinsic procedure is referenced;
Specify intrinsic or non_intrinsic on a use statement for a module;
Use compiler options to detect use of non-standard intrinsic procedures and modules.
So the bottom line is intrinsic means only “provided by the processor”, and not necessarily part of the standard. Or in other words standard procedures and modules are a subset of the intrinsic ones.
I think the way intrinsic modules work is that the definitions, interfaces, and procedures are provided by the compiler without any extra effort. For a user module, that extra effort is locating the .mod file and the .o file. For an intrinsic module, those files do not really need to exist, the compiler is allowed to make everything available “as if” they exist during the compile step and then later during the link step.
If an intrinsic module is defined by the standard, then I think its name starts with iso_. If it is a nonstandard intrinsic module, e.g. one provided by a specific compiler, then I think its name should not begin with iso_, that would be confusing. That goes also for user modules, they should not begin with iso_, although, as far as I know, that is allowed by the standard.
The intrinsic and non_intrinsic clauses allow the programmer to avoid name conflicts and to pick the right module when those conflicts do occur.