# C binding with nullable argument

**URL:** <https://fortran-lang.discourse.group/t/c-binding-with-nullable-argument/9324>\
**Category:** Uncategorized\
**Created:** [March 10, 2025, 9:14am UTC](https://fortran-lang.discourse.group/t/c-binding-with-nullable-argument/9324 "2025-03-10T09:14:54Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![nja](https://avatars.discourse-cdn.com/v4/letter/n/ed8c4c/32.png) [@nja](https://fortran-lang.discourse.group/u/nja)\
**Post date:** [March 10, 2025, 9:14am UTC](https://fortran-lang.discourse.group/t/c-binding-with-nullable-argument/9324/1 "2025-03-10T09:14:54Z")

</div>

I’m writing a Fortran binding to a C function looking like:

```C
void some_function(int * argument);

```

Argument is passed as pointer because it can be NULL. The user can pass a pointer to a specific integer value to tune the function’s behavior, _or_ pass NULL to let the function select a reasonable default value.

So far I was binding this with:

```fortran
subroutine some_function(argument) bind(c)
  import :: c_int
  integer(c_int) :: argument ! without the "value" attribute
end

```

But this form forbids passing `c_null_ptr`:

```fortran
call some_function(3)
call some_function(c_null_ptr) ! gfortran: Error: Type mismatch in argument 'argument' at (1); passed TYPE(c_ptr) to INTEGER(4)

```

This makes me say this binding would be closer to the C++ form:

```c++
void some_function(int& argument);

```

But to bind my C function with nullable argument, I’m forced to write:

```fortran
subroutine some_function(argument) bind(c)
  import :: c_ptr
  type(c_ptr), value :: argument
end

```

So the original type of `argument` is lost, and some extra work is required for the caller:

```fortran
integer, target :: v
v = 3
call some_function(c_loc(v))
call some_function(c_null_ptr) ! This is OK now

```

As a nasty consequence, it’s now possible to pass anything to my function:

```fortran
real, target :: u
u = 8.45
call some_function(c_loc(u)) ! Oops

```

So:

1. Is my understanding correct?
2. If so, is there another way to do this?

I was considering something hacky:

```fortran
interface hack
    subroutine some_function_int(argument) bind(c, name="some_function")
      import :: c_int
      integer(c_int) :: argument ! without the "value" attribute
    end
    subroutine some_function_ptr(argument) bind(c, name="some_function")
      import :: c_ptr
      type(c_ptr), value :: argument
    end
end interface

```

It seems to work:

```fortran
integer, target :: v

call hack(3)
call hack(c_null_ptr)
v = 15
call hack(v)
v = 3
call hack(c_loc(v))

```

With a dummy implementation:

```c
#include <stdio.h>

int some_function(int * value)
{
    if(value == NULL)
    {
        printf("C > value received = NULL !!\n");
    }
    else
    {
        printf("C > value received = %d\n", *value);
    }
}

```

I get:

```auto
C > value received = 3
C > value received = NULL !!
C > value received = 15
C > value received = 3

```

But I’m not sure if it works by pure chance, and I’m worried about the legitimacy of this.

---

<div class="post-metadata">

**Author:** ![septc](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/septc/32/77_2.png) [@septc](https://fortran-lang.discourse.group/u/septc)\
**Post date:** [March 10, 2025, 9:52am UTC](https://fortran-lang.discourse.group/t/c-binding-with-nullable-argument/9324/2 "2025-03-10T09:52:17Z")

</div>

I remember I read somewhere (Stackoverflow?) that null will be sent when an `optional` argument receives no actual argument (indeed, the following code seems to work). But I am not sure whether this behavior is guaranteed by the Standards for C interoperability (or even within pure Fortran codes), so I would like to know if that is the case.

```fortran
!! fmain.f90
program main
    use iso_c_binding, only: c_int
    implicit none
    interface
        subroutine mysub( n ) bind(c,name="mysub")
            import
            integer(c_int), optional :: n
        end subroutine
    end interface

    call mysub( n=100 )
    call mysub()
end

```

```c
// cfunc.f
#include <stdio.h>

void mysub(int * value)
{
    if(value == NULL)
    {
        printf("C > value received = NULL !!\n");
    }
    else
    {
        printf("C > value received = %d\n", *value);
    }
}

```

```shell
$ gfortran cfunc.c fmain.f90 && ./a.out
C > value received = 100
C > value received = NULL !!

```

---

<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:** [March 10, 2025, 10:22am UTC](https://fortran-lang.discourse.group/t/c-binding-with-nullable-argument/9324/3 "2025-03-10T10:22:21Z")

</div>

> [@septc](#):
>
> But I am not sure whether this behavior is guaranteed by the Standards for C interoperability (or even within pure Fortran codes), so I would like to know if that is the case.

AFAIK, this is guaranteed since F2018. For instance in J3/24-007, section 18.3.7,

> If an interoperable procedure defined by means other than Fortran has an optional dummy argument, and the corresponding actual argument in a reference from Fortran is absent, the procedure is invoked with a null pointer for that argument. If an interoperable procedure defined by means of Fortran is invoked by a C function, an optional dummy argument is absent if and only if the corresponding argument in the invocation is a null pointer.

An explanation of this feature can also be found in Modern Fortran explained: incorporating Fortran 2023, section 20.14.

* * *

So the solution, would be to use:

```fortran
subroutine some_function(argument) bind(c)
  import :: c_int
  integer(c_int), optional :: argument ! without "value" attribute
end subroutine

```

---

<div class="post-metadata">

**Author:** ![septc](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/septc/32/77_2.png) [@septc](https://fortran-lang.discourse.group/u/septc)\
**Post date:** [March 10, 2025, 10:29am UTC](https://fortran-lang.discourse.group/t/c-binding-with-nullable-argument/9324/4 "2025-03-10T10:29:37Z")

</div>

Ohh… thanks very much for your information! The web page I read before (possibly Stackoverflow) did not cite the original reference, so I was not very sure about this feature. Also, my edition of Modern Fortran Explained is somewhat old (green one), so maybe it’s time to get newer ones…

---

<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:** [March 10, 2025, 10:31am UTC](https://fortran-lang.discourse.group/t/c-binding-with-nullable-argument/9324/5 "2025-03-10T10:31:26Z")

</div>

The `optional` argument appears already in the F2018 version of MFE (the red book).

---

<div class="post-metadata">

**Author:** ![nja](https://avatars.discourse-cdn.com/v4/letter/n/ed8c4c/32.png) [@nja](https://fortran-lang.discourse.group/u/nja)\
**Post date:** [March 10, 2025, 12:15pm UTC](https://fortran-lang.discourse.group/t/c-binding-with-nullable-argument/9324/6 "2025-03-10T12:15:10Z")

</div>

This is very interesting, it could be helpful when the argument can be considered optional. But it’s not always the case, I can have more, non-optional (and non-pointer) arguments following:

```c
void some_tricky_function(int * nullable_argument, int another_argument);

```

The C API is not necessarily designed to be Fortran-friendly in the first place. I could make intermediate C functions to adapt the signature of course.

---

<div class="post-metadata">

**Author:** ![PierU](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/pieru/32/1848_2.png) [@PierU](https://fortran-lang.discourse.group/u/PierU)\
**Post date:** [March 10, 2025, 1:32pm UTC](https://fortran-lang.discourse.group/t/c-binding-with-nullable-argument/9324/7 "2025-03-10T13:32:55Z")

</div>

> [@nja](#):
>
> This is very interesting, it could be helpful when the argument can be considered optional. But it’s not always the case, I can have more, non-optional (and non-pointer) arguments following:
> 
> `void some_tricky_function(int * nullable_argument, int another_argument);`

I don’t think it’s a problem. The Fortran interface would simply be:

```auto
subroutine some_tricky_function(argument,another_argument) bind(c)
  import :: c_int
  integer(c_int), optional :: argument
  integer(c_int), value :: another_argument
end subroutine

```

---

<div class="post-metadata">

**Author:** ![nja](https://avatars.discourse-cdn.com/v4/letter/n/ed8c4c/32.png) [@nja](https://fortran-lang.discourse.group/u/nja)\
**Post date:** [March 10, 2025, 1:56pm UTC](https://fortran-lang.discourse.group/t/c-binding-with-nullable-argument/9324/8 "2025-03-10T13:56:53Z")

</div>

I was not aware that optional arguments could be at any place in a function’s signature. I thought they had to be placed _after_ compulsory arguments, like C++ or Python.

This becomes an interesting solution indeed.

---

<div class="post-metadata">

**Author:** ![PierU](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/pieru/32/1848_2.png) [@PierU](https://fortran-lang.discourse.group/u/PierU)\
**Post date:** [March 10, 2025, 4:39pm UTC](https://fortran-lang.discourse.group/t/c-binding-with-nullable-argument/9324/9 "2025-03-10T16:39:45Z")

</div>

The only constraint is that if an optional argument is omitted in a call, all the following arguments (optional or not) must be referenced with a keyword:

```auto
call some_tricky_function(another_argument=...)`

```

---

<div class="post-metadata">

**Author:** ![sblionel](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/sblionel/32/853_2.png) [@sblionel](https://fortran-lang.discourse.group/u/sblionel)\
**Post date:** [March 11, 2025, 12:42am UTC](https://fortran-lang.discourse.group/t/c-binding-with-nullable-argument/9324/10 "2025-03-11T00:42:21Z")

</div>

As I mention in another thread, Fortran 2023 adds the syntax `.NIL.` to indicate omission of an optional argument, so you would no longer be required to use keyword argument names. I’m not aware that any compiler supports this yet.
