Gfortran,bindc ,printf

As @FortranFan remarked in his previous post, variadic functions are not interoperable. The prototype of printf is this:

int printf ( const char * format, ... );

If you go searching for a function called printf in glibc, you won’t find it. What you will find is this:

int
__printf (const char *format, ...)
{
  va_list arg;
  int done;

  va_start (arg, format);
  done = vfprintf (stdout, format, arg);
  va_end (arg);

  return done;
}

A macro is used to associate printf to __printf

ldbl_strong_alias (__printf, printf);

where the macro is

#define ldbl_strong_alias(name, aliasname) strong_alias (name, aliasname)

As you can see the macro just calls another macro, defined somewhere else. I’ve found a blog on " Where the printf() Rubber Meets the Road" which explains how printf works. You can also start in glibc/stdio-common/printf.c and work your way down.

If you search for printf in libc there is a matching symbol:

Click to expand
$ nm -D /lib/x86_64-linux-gnu/libc.so.6 | grep printf
0000000000061f20 T __asprintf
0000000000061f20 W asprintf
000000000012f640 T __asprintf_chk
0000000000061fe0 T dprintf
000000000012f720 T __dprintf_chk
0000000000061c00 T fprintf
000000000012e0b0 T __fprintf_chk
0000000000086450 W fwprintf
000000000012f0d0 T __fwprintf_chk
0000000000061c00 W _IO_fprintf
0000000000061cc0 T _IO_printf
0000000000061e50 T _IO_sprintf
000000000005b8d0 T _IO_vfprintf
0000000000085160 T _IO_vsprintf
000000000008c530 W obstack_printf
000000000012f800 T __obstack_printf_chk
000000000008c360 W obstack_vprintf
000000000012f8c0 T __obstack_vprintf_chk
000000000005ecf0 T parse_printf_format
0000000000061cc0 T printf
000000000012dfe0 T __printf_chk
000000000005ea00 T __printf_fp
0000000000061130 T printf_size
0000000000061be0 T printf_size_info
...

But I doubt it’s what you expect it to be.

I also doubt it’s a good idea to define the C-formatted string literal in Fortran. printf stands for formatted printing. If you call printf in C, your compiler will check the arguments match the string literal. For example:

/* test_printf.c */
#include <stdio.h>

int main(int argc, char const *argv[])
{
    printf("%f\n", 42);
    return 0;
}
$ gcc test_printf.c 
test_printf.c: In function ‘main’:
test_printf.c:6:18: warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘int’ [-Wformat=]
    6 |         printf("%f\n", 42);
      |                 ~^     ~~
      |                  |     |
      |                  |     int
      |                  double
      |                 %d

If you’d like to use printf for some reason, pass the arguments to C, and then call printf on the C side.

1 Like