# Sharing constants between Fortran and C

**URL:** <https://fortran-lang.discourse.group/t/sharing-constants-between-fortran-and-c/3446>\
**Category:** Uncategorized\
**Created:** [May 12, 2022, 8:21pm UTC](https://fortran-lang.discourse.group/t/sharing-constants-between-fortran-and-c/3446 "2022-05-12T20:21:28Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [May 12, 2022, 8:21pm UTC](https://fortran-lang.discourse.group/t/sharing-constants-between-fortran-and-c/3446/1 "2022-05-12T20:21:28Z")

</div>

I can make module variables protected so that they cannot be changed in Fortran outside the module, but if I share them with C, they can be changed in the C code. Is there a workaround? For example, compiling and running

```auto
module constants_mod
use iso_c_binding, only: c_double
implicit none
real(kind=c_double), bind(c), protected :: pi, sqrt_2
contains
subroutine set_constants()
pi = 3.14159265359_c_double
sqrt_2 = 1.41421356237_c_double
end subroutine set_constants
end module constants_mod

program main
use constants_mod, only: set_constants
interface
subroutine print_constants() bind(c)
end subroutine print_constants
end interface
call set_constants()
call print_constants()
call print_constants()
end program main

```

with

```auto
#include <stdio.h>

double pi, sqrt_2;

void print_constants() {
	printf("\npi = %f",pi);
	printf("\nsqrt_2 = %f",sqrt_2);
	pi = pi*2; // bad
}

```

gives

```auto
pi = 3.141593
sqrt_2 = 1.414214
pi = 6.283185
sqrt_2 = 1.414214

```

---

<div class="post-metadata">

**Author:** ![vmagnin](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/vmagnin/32/28_2.png) [@vmagnin](https://fortran-lang.discourse.group/u/vmagnin)\
**Post date:** [May 12, 2022, 8:35pm UTC](https://fortran-lang.discourse.group/t/sharing-constants-between-fortran-and-c/3446/2 "2022-05-12T20:35:30Z")

</div>

There is probably no solution on the Fortran side.  
On the C side, they should be declared constants:

```nohighlight
const double pi, sqrt_2;

```

---

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [May 12, 2022, 9:14pm UTC](https://fortran-lang.discourse.group/t/sharing-constants-between-fortran-and-c/3446/3 "2022-05-12T21:14:58Z")

</div>

> [@vmagnin](#):
>
> There is probably no solution on the Fortran side.  
> On the C side, they should be declared constants:
> 
> ```C
> const double pi, sqrt_2;
> 
> ```

I had tried that, but when I change the C code to

```auto
#include <stdio.h>

const double pi;
const double sqrt_2;

void print_constants() {
	printf("\npi = %f",pi);
	printf("\nsqrt_2 = %f",sqrt_2);
}

```

and compile with gfortran and gcc, the resulting program runs on WSL2 but crashes on Windows with

`Program received signal SIGSEGV: Segmentation fault - invalid memory reference.`

Reading [What kind of optimization does const offer in C/C++? - Stack Overflow](https://stackoverflow.com/questions/27466642/what-kind-of-optimization-does-const-offer-in-c-c) it appears that a C compiler has the freedom to optimize away `foo` in

`const int foo = 42;`

so I don’t know if such a variable interoperates with

`integer(kind=c_int) :: foo`

---

<div class="post-metadata">

**Author:** ![MarDie](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/mardie/32/54_2.png) [@MarDie](https://fortran-lang.discourse.group/u/MarDie)\
**Post date:** [May 12, 2022, 9:30pm UTC](https://fortran-lang.discourse.group/t/sharing-constants-between-fortran-and-c/3446/4 "2022-05-12T21:30:03Z")

</div>

Probably the cleanest _single sourt of truth_ solution is the definition via the preprocessor.

---

<div class="post-metadata">

**Author:** ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)\
**Post date:** [May 12, 2022, 9:32pm UTC](https://fortran-lang.discourse.group/t/sharing-constants-between-fortran-and-c/3446/5 "2022-05-12T21:32:58Z")

</div>

It’s good fun to probe the limits of interoperability, but sometimes it’s best to just stick to an in-language concept.

Joining @MarDie’s answer, the canonical way of defining parameters in C is with preprocessor macros. The math constants in [`<math.h>`](https://pubs.opengroup.org/onlinepubs/009604499/basedefs/math.h.html) are one example.

---

<div class="post-metadata">

**Author:** ![mecej4](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/mecej4/32/855_2.png) [@mecej4](https://fortran-lang.discourse.group/u/mecej4)\
**Post date:** [May 13, 2022, 2:01am UTC](https://fortran-lang.discourse.group/t/sharing-constants-between-fortran-and-c/3446/6 "2022-05-13T02:01:02Z")

</div>

I think that the problem that you have to contend with is your expectation that a restriction that you specify in the Fortran program ( **protected** ) should be known to and honored/enforced by the C routine, or vice versa.

Do the C-interoperability rules in the applicable Fortran standard specify such behavior?

If not, that level of cooperation between the Fortran compiler and its companion C compiler may exist with certain compiler pairs, but not so with others. If you do not trust the C compiler and/or the C routine to leave your shared variables unchanged, only make “throwaway” copies available to C; load the copies with values before calling C; make the call, and reload the copies after the C call returns.

---

<div class="post-metadata">

**Author:** ![Pap](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/pap/32/1305_2.png) [@Pap](https://fortran-lang.discourse.group/u/Pap)\
**Post date:** [May 13, 2022, 8:16am UTC](https://fortran-lang.discourse.group/t/sharing-constants-between-fortran-and-c/3446/7 "2022-05-13T08:16:05Z")

</div>

The `parameter` atribute conflicts with the `bind(c)` attribute. That alone suggests interoperability of constants is problematic - presumably because C’s global constants are basically macros. I would either interop copies of the original constants (as @mecej4 recommended), or just define `print_constants` with arguments, something like:

```auto
program main
use constants_mod!, only: set_constants
implicit none
interface
  subroutine print_constants(pi, sqrt_2) bind(c)
  use iso_c_binding, only: c_double
  real(kind=c_double), value :: pi, sqrt_2
  end subroutine print_constants
end interface
call set_constants()
call print_constants(pi, sqrt_2)
call print_constants(pi, sqrt_2)
end program main

```

with

```auto
#include <stdio.h>

void print_constants(const double pi, const double sqrt_2) {
	printf("\npi = %f",pi);
	printf("\nsqrt_2 = %f",sqrt_2);
	pi = pi*2; // This will cause an error, as it should!
}

```

If `print_constants` really needs to modify the constants, it should define local copies of those. However, I realize this is just a stripped short example of the real code. If said real code needs to modify `pi` or `sqrt_2`, remove the `const` attribute in C-side. Even then, the original constants in F-side will remain intact.

---

<div class="post-metadata">

**Author:** ![lkedward](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/lkedward/32/72_2.png) [@lkedward](https://fortran-lang.discourse.group/u/lkedward)\
**Post date:** [May 13, 2022, 10:19am UTC](https://fortran-lang.discourse.group/t/sharing-constants-between-fortran-and-c/3446/8 "2022-05-13T10:19:53Z")

</div>

> [@Beliavsky](#):
>
> … it appears that a C compiler has the freedom to optimize away…

Could you try the `extern` keyword in the c code to avoid this?

_e.g._

```auto
#include <stdio.h>

extern const double pi;
extern const double sqrt_2;

void print_constants() {
	printf("\npi = %f",pi);
	printf("\nsqrt_2 = %f",sqrt_2);
}

```

---

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [May 13, 2022, 12:39pm UTC](https://fortran-lang.discourse.group/t/sharing-constants-between-fortran-and-c/3446/9 "2022-05-13T12:39:55Z")

</div>

> [@lkedward](#):
>
> > [@Beliavsky](#):
> >
> > … it appears that a C compiler has the freedom to optimize away…
> 
> Could you try the `extern` keyword in the c code to avoid this?
> 
> _e.g._
> 
> ```auto
> #include <stdio.h>
> 
> extern const double pi;
> extern const double sqrt_2;
> 
> void print_constants() {
> printf("\npi = %f",pi);
> printf("\nsqrt_2 = %f",sqrt_2);
> }
> 
> ```

Thanks. Now the program no longer crashes on Windows, and it runs correctly as before on WSL2.  
A program where I add another C source file

```auto
extern const double pi;

double area_circle(double radius) {
	return pi*radius*radius;
}

```

and call the function in it also works.

---

<div class="post-metadata">

**Author:** ![dwwork](https://avatars.discourse-cdn.com/v4/letter/d/71e660/32.png) [@dwwork](https://fortran-lang.discourse.group/u/dwwork)\
**Post date:** [May 18, 2022, 12:10am UTC](https://fortran-lang.discourse.group/t/sharing-constants-between-fortran-and-c/3446/10 "2022-05-18T00:10:46Z")

</div>

I’m a bit late to the party, but the `extern` keyword is necessary on the C side.

```auto
const double pi;

```

This defines an uninitialized const variable pi. (Sadly, it is valid C to leave it uninitialized!)

```auto
extern const double pi;

```

This declares that somewhere, in a different object file, there will be a const variable pi, and the linker should go and find it. Since the actual definition is in your fortran module, this is the form that you want for the C code.

The const keyword basically means “read-only”. It’s less formal than fortran’s parameter keyword.
