Question

Within the context of a mixed C/Fortran application, is there a way to check that the compiler knows "iso_c_binding" (for instance GCC 4.1.2 doesn't know it, while 4.3.4 does), like a pre-processing directive or something? I cannot afford to simply check GCC's version since I may use other compilers.

Thanks

Was it helpful?

Solution

Your only two options, that I can think of, are to roll your own version of iso_c_binding for systems which do not have this module (as suggested by @HighPerformanceMark) or to use preprocessors to conditionally compile parts of your code depending on the compiler version. In both cases you will have to work to ensure that your code is portable across systems. As suggested by @HighPerformanceMark you can copy and paste an open-source implementation of iso_c_binding, but for each new system you port your code to you will have to check that this implementation is correct.

Depending on how you want your code to behave if iso_c_binding is not avaiable I would recommend using the preprocessor method. You state that "I cannot afford to simply check GCC's version since I may use other compilers". However, all your options will require work on your part to maintain your code for use on different systems, the preprocessor method requires, in my opionion, the least amount of work.

The following code determines the compiler version using the preprocessor and can be used to conditionally compile your code based on whether the compiler versions meets some minimum version. For gfortran:

If GNU Fortran invokes the preprocessor, __GFORTRAN__ is defined and __GNUC__, __GNUC_MINOR__ and __GNUC_PATCHLEVEL__ can be used to determine the version of the compiler.

In a file, say precomp.inc I would include a number of precompiler checks which determine which features to include in you code. For example, I would check the compiler version and, if it supports the use of the iso_c_binding module I would define a preprocessor macro HAS_ISO_C_BINDING (or similar). The file precomp.inc can then be included in other parts of your code. This file could look something like:

!> \file precomp.inc
!! Preprocessor feature detection.

#if defined(__GFORTRAN__)

#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 3
#define HAS_ISO_C_BINDING 1
#else
#define HAS_ISO_C_BINDING 0
#endif

#elif defined(__INTEL_COMPILER)
#error "I haven't implemented this yet..."

#else
#error "Compiler not yet supported."

#endif

The error in the final #else clause could be replaced with HAS_ISO_C_BINDING=0, if you want to be able to compile without support for the iso_c_binding module.

Your Fortran source would look something like

program main

#include 'precomp.h'
#if HAS_ISO_C_BINDING
use iso_c_binding
#endif

implicit none

! Some code...

#if HAS_ISO_C_BINDING
! Code which depends on iso_c_binding
#else
! Fallback code
#end if

! Some more code...

end program main

Again, the right method to use depends on how you want to code to compile if iso_c_binding is not avaiable. If your code needs to compile on systems without this module then @HighPerformanceMark's answer is probably better. If you can just raise an error at compile time or if you have some fallback code if iso_c_binding is not avaiable then I would use this preprocessor method since this only requires one additional check to be added for each new compiler you need to use.

OTHER TIPS

The question is misdirected. Practically what you are asking is whether the companion Fortran processor (assuming it exists) supports the necessary aspects of C interoperability that your C program requires it to. There is a lot more to C interoperability than just the presence of an intrinsic module.

For example, it is quite legitimate for a F2003 processor to supply an ISO_C_BINDING that then says that nearly all aspects of C interoperability are not supported (constants like C_FLOAT, C_REAL, etc, could have a negative value, meaning "not supported").

So unless your usage of C interoperability is incredibly basic (there are some aspects that must be supported by a F2003 processor - such as C_INT, C_LOC, C_F_POINTER, etc) the only practical ways to ascertain capability are:

  • To compile a small Fortran program that explicitly USE's the required entities and tests their values (different negative numbers explain why the Fortran processor doesn't provide support). As others have written, the success or failure of the compile, and perhaps subsequent program output if the compile was successful, can then be used to configure other aspects of your build.

  • To Read The Fortran processor's Manual.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top