Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29249 Discussions

type, parameter, bind(c,name='myName' :: iConst = 2

john3
Beginner
1,291 Views

Interoperability with C for Fortran parameters:

Why can one not use the parameter key word when trying to make a variable seen on the C side.

This works:

integer(4), bind(c,name='myName') :: myname

This does not (C side can not find the name)

integer(4), parameter, bind(C,name-'myConst') :: myConst = 3

Thanks.

0 Kudos
9 Replies
Jugoslav_Dujic
Valued Contributor II
1,291 Views
I don't expect that to work with parameters at all: a parameter is not a variable, and does not have necessarily any storage associated (i.e. it is a compile-time only thing, linker does not even see it), thus there's nothing to bind in the general case. However, I'd expect the compiler to complain here.
0 Kudos
Arjen_Markus
Honored Contributor II
1,291 Views

The debugger does not see them either (which is unfortunate at times)

Regards,

Arjen

0 Kudos
Steven_L_Intel1
Employee
1,291 Views

The debugger can see parameters if you enable the /debug:parameter option.

Jugoslav has the correct explanation for the original question. He is also correct in saying that the compiler should complain - I will report this.

0 Kudos
Arjen_Markus
Honored Contributor II
1,291 Views

I did not know that - useful to know, indeed.

Regards,

Arjen

0 Kudos
john3
Beginner
1,291 Views

OK, that makes sense. So, how would one have the same set of constants on Fortran and C side where they would be specified, say, only on the Fortran side?

0 Kudos
Steven_L_Intel1
Employee
1,291 Views

There's no way to do that, unless you have some sort of tool that automatically translates C #defines to Fortran PARAMETER. Really, C doesn't have the exact equivalent of PARAMETER.

I suppose another option is to have a .h file that has the #define declarations and then #include this into Fortran with the preprocessor enabled. It's not quite the same as PARAMETER but may do what you want.

0 Kudos
john3
Beginner
1,291 Views

My work around was to use C enum and Fortran enum with a series of parameters. Each side (C and Fortran) then evaluate the enum's to the same values.

This works. But would not like to rely on having two sets of defined constants.

0 Kudos
JVanB
Valued Contributor II
1,291 Views

It seems to work with gcc/gfortran.

[bash]/* constants.c */

const double k_B = 1.38054e-23;
/* c_sub.c */
#include 
extern double k_B;

void c_sub()
{
   printf("k_B = %en", k_B);
}
! use_constants.f90
! compilation sequence:
! gcc -Wall -c constants.c
! gcc -Wall -c c_sub.c
! gfortran -Wall use_constants.f90 constants.o c_sub.o -ouse_constants
! Then run the resulting use_constants.exe

module has_constants
   use ISO_C_BINDING
   implicit none
   real(C_DOUBLE), bind(C,name='k_B') :: k_B
end module has_constants

program test
   use has_constants
   implicit none
   interface
      subroutine C_sub() bind(C,name='c_sub')
      end subroutine C_sub
   end interface

   write(*,*) 'k_B = ', k_B
   call c_sub
   k_b = 0
   write(*,*) 'k_B = ', k_B
end program test
[/bash]
[bash]When the resulting use_constants.exe is executed, we get:[/bash]
[bash]

k_B = 1.38054000000000004E-023

k_B = 1.380540e-023

With no further output indicating that k_B was indeed linked as a constant, the access violation just didn't get trapped.

Hopefully you can read this even though the formatting didn't work. I have been too sick to sleep the last two nights so I don't have the energy to puzzle out the forum software.

[/bash]
0 Kudos
Steven_L_Intel1
Employee
1,291 Views

"const" in C is not the same as a PARAMETER constant. It is a variable which you are not allowed to change. Fortran has a similar concept called PROTECTED. But if you want to do it this way, it will work in Intel Fortran as well.

I tried your test case with Intel Visual Fortran and MSVC. I could not get the C definition to "take" in a separate source (the C code couldn't see it either) so I moved it into the C source replacing the "extern". This worked, and an access violation occurred when the Fortran code tried to change it.

0 Kudos
Reply