Stdout buffer in gfortran

Yes, let me provide the simplified test cases.

C:

void main(){
    while (1)
    {
        for(int i=49;i<91;i++){putchar(i);}
        puts("");
    }
    
}

Fortran:

program test
    implicit none
    INTEGER::i

    do while(.true.)
        do i=49,90
            WRITE(*,"(A)",advance="no")achar(i)
        enddo
        print*,""
    enddo
end program test

Both compiled with gcc and gfortran respectively without any options. using strace ./a.out >/dev/null on both binaries:

Syscalls by C program:

write(1, "123456789:;<=>?@ABCDEFGHIJKLMNOP"..., 4096) = 4096
write(1, "<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\n"..., 4096) = 4096
write(1, "GHIJKLMNOPQRSTUVWXYZ\n123456789:;"..., 4096) = 4096
write(1, "RSTUVWXYZ\n123456789:;<=>?@ABCDEF"..., 4096) = 4096
write(1, "23456789:;<=>?@ABCDEFGHIJKLMNOPQ"..., 4096) = 4096
write(1, "=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\n1"..., 4096) = 4096
write(1, "HIJKLMNOPQRSTUVWXYZ\n123456789:;<"..., 4096) = 4096
write(1, "STUVWXYZ\n123456789:;<=>?@ABCDEFG"..., 4096) = 4096
write(1, "3456789:;<=>?@ABCDEFGHIJKLMNOPQR"..., 4096) = 4096

Writing 4096 bytes at a time per syscall even though putchar (it can be replaced by printf("%c",i) without changing results) function is printing character by character.

But same thing on fortran is written character by character gfortran generated binary,

Syscalls by Fortran program:

write(1, "?", 1)                        = 1
write(1, "@", 1)                        = 1
write(1, "A", 1)                        = 1
write(1, "B", 1)                        = 1
write(1, "C", 1)                        = 1
write(1, "D", 1)                        = 1
write(1, "E", 1)                        = 1
write(1, "F", 1)                        = 1
write(1, "G", 1)                        = 1
write(1, "H", 1)                        = 1
write(1, "I", 1)                        = 1
write(1, "J", 1)                        = 1
write(1, "K", 1)                        = 1

I haven’t looked into gfortran’s implementation. I have not tested with any other compiler, either.
But as you said it is linked to libc

❯ ldd a.out
	linux-vdso.so.1 (0x00007fff5b46a000)
	libgfortran.so.5 => /lib64/libgfortran.so.5 (0x00007f0cf62c2000)
	libm.so.6 => /lib64/libm.so.6 (0x00007f0cf617e000)
	libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f0cf6163000)
	libquadmath.so.0 => /lib64/libquadmath.so.0 (0x00007f0cf6119000)
	libc.so.6 => /lib64/libc.so.6 (0x00007f0cf5f4a000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f0cf6589000)
5 Likes