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

Waiting on C function to return before proceeding

MWind2
New Contributor III
1,205 Views

I noticed a 'Hello World' at end of programming when debugging or exe on command line, but when used with redirect to file as in ftn_c.exe >ftn_c.txt, it appears before c function printf. (Or is this an OS(W10) "feature"?)

How do I make it wait for C function to return before proceeding?

!********************************
module ftn_C_2
   interface 
     integer (C_INT) function CPP_Library_Function & 
     (sendbuf, sendcount, recvcounts) & 
        BIND(C, name='CPP_Library_Function') 
        use, intrinsic :: ISO_C_BINDING  
        implicit none 
        type (C_PTR), value :: sendbuf 
        integer (C_INT), value :: sendcount 
        type (C_PTR), value :: recvcounts 
     end function CPP_Library_Function 
   end interface 
end module ftn_C_2
!  ftn_c.f90 
!
!  FUNCTIONS:
!  ftn_c - Entry point of console application.
!

!****************************************************************************
!
!  PROGRAM: ftn_c
!
!  PURPOSE:  Entry point for the console application.
!
!********************************************
program ftn_c
use, intrinsic :: ISO_C_BINDING, only: C_INT, C_FLOAT, C_LOC 
use ftn_C_2 
implicit none

! Variables
CHARACTER*1   CR 
CHARACTER*1   LF 
CHARACTER*1   NULL 
INTEGER :: CRET
real (C_FLOAT), target :: send(100) 
integer (C_INT) :: sendcount 
integer (C_INT), ALLOCATABLE, target :: recvcounts(:)
integer :: i
CR=CHAR(13) 
LF   = CHAR(10) 
NULL = CHAR(0) 
send(1)=1.0
do i=1,99
    send(1+i)=2.0*send(i)
end do

!
! Body of ftn_c
    ALLOCATE( recvcounts(100) ) 
!
    sendcount = 100
    CRET = CPP_Library_Function(C_LOC(send), sendcount, C_LOC(recvcounts)) 
!
    print *, CR // LF //'Hello World'
end program ftn_c

 

 

#include <cstdio>
extern "C" int CPP_Library_Function(void* sendbuf, int sendcount, int *recvcounts) {
	for (int i = 0; i < sendcount; i++) {
		if (i > 0 && i % 4 == 0)printf("\n");
		printf("  send(%02d)=%e  ", i, *((float*)(sendbuf)+i));
	}
	return 0x11;
};

 

ftn_c.exe > ftn_c.txt:

Hello World
  send(00)=1.000000e+00    send(01)=2.000000e+00    send(02)=4.000000e+00    send(03)=8.000000e+00  

  send(04)=1.600000e+01    send(05)=3.200000e+01    send(06)=6.400000e+01    send(07)=1.280000e+02  

  send(08)=2.560000e+02    send(09)=5.120000e+02    send(10)=1.024000e+03    send(11)=2.048000e+03  

  send(12)=4.096000e+03    send(13)=8.192000e+03    send(14)=1.638400e+04    send(15)=3.276800e+04  

  send(16)=6.553600e+04    send(17)=1.310720e+05    send(18)=2.621440e+05    send(19)=5.242880e+05  

  send(20)=1.048576e+06    send(21)=2.097152e+06    send(22)=4.194304e+06    send(23)=8.388608e+06  

  send(24)=1.677722e+07    send(25)=3.355443e+07    send(26)=6.710886e+07    send(27)=1.342177e+08  

  send(28)=2.684355e+08    send(29)=5.368709e+08    send(30)=1.073742e+09    send(31)=2.147484e+09  

  send(32)=4.294967e+09    send(33)=8.589935e+09    send(34)=1.717987e+10    send(35)=3.435974e+10  

  send(36)=6.871948e+10    send(37)=1.374390e+11    send(38)=2.748779e+11    send(39)=5.497558e+11  

  send(40)=1.099512e+12    send(41)=2.199023e+12    send(42)=4.398047e+12    send(43)=8.796093e+12  

  send(44)=1.759219e+13    send(45)=3.518437e+13    send(46)=7.036874e+13    send(47)=1.407375e+14  

  send(48)=2.814750e+14    send(49)=5.629500e+14    send(50)=1.125900e+15    send(51)=2.251800e+15  

  send(52)=4.503600e+15    send(53)=9.007199e+15    send(54)=1.801440e+16    send(55)=3.602880e+16  

  send(56)=7.205759e+16    send(57)=1.441152e+17    send(58)=2.882304e+17    send(59)=5.764608e+17  

  send(60)=1.152922e+18    send(61)=2.305843e+18    send(62)=4.611686e+18    send(63)=9.223372e+18  

  send(64)=1.844674e+19    send(65)=3.689349e+19    send(66)=7.378698e+19    send(67)=1.475740e+20  

  send(68)=2.951479e+20    send(69)=5.902958e+20    send(70)=1.180592e+21    send(71)=2.361183e+21  

  send(72)=4.722366e+21    send(73)=9.444733e+21    send(74)=1.888947e+22    send(75)=3.777893e+22  

  send(76)=7.555786e+22    send(77)=1.511157e+23    send(78)=3.022315e+23    send(79)=6.044629e+23  

  send(80)=1.208926e+24    send(81)=2.417852e+24    send(82)=4.835703e+24    send(83)=9.671407e+24  

  send(84)=1.934281e+25    send(85)=3.868563e+25    send(86)=7.737125e+25    send(87)=1.547425e+26  

  send(88)=3.094850e+26    send(89)=6.189700e+26    send(90)=1.237940e+27    send(91)=2.475880e+27  

  send(92)=4.951760e+27    send(93)=9.903520e+27    send(94)=1.980704e+28    send(95)=3.961408e+28  

  send(96)=7.922816e+28    send(97)=1.584563e+29    send(98)=3.169127e+29    send(99)=6.338253e+29  powershell

debug console stepping through code or exe at cmd or powershell:

PS C:\mw\c\vs2017\ftn_c\ftn_c\x64\Debug> .\ftn_c
  send(00)=1.000000e+00    send(01)=2.000000e+00    send(02)=4.000000e+00    send(03)=8.000000e+00
  send(04)=1.600000e+01    send(05)=3.200000e+01    send(06)=6.400000e+01    send(07)=1.280000e+02
  send(08)=2.560000e+02    send(09)=5.120000e+02    send(10)=1.024000e+03    send(11)=2.048000e+03
  send(12)=4.096000e+03    send(13)=8.192000e+03    send(14)=1.638400e+04    send(15)=3.276800e+04
  send(16)=6.553600e+04    send(17)=1.310720e+05    send(18)=2.621440e+05    send(19)=5.242880e+05
  send(20)=1.048576e+06    send(21)=2.097152e+06    send(22)=4.194304e+06    send(23)=8.388608e+06
  send(24)=1.677722e+07    send(25)=3.355443e+07    send(26)=6.710886e+07    send(27)=1.342177e+08
  send(28)=2.684355e+08    send(29)=5.368709e+08    send(30)=1.073742e+09    send(31)=2.147484e+09
  send(32)=4.294967e+09    send(33)=8.589935e+09    send(34)=1.717987e+10    send(35)=3.435974e+10
  send(36)=6.871948e+10    send(37)=1.374390e+11    send(38)=2.748779e+11    send(39)=5.497558e+11
  send(40)=1.099512e+12    send(41)=2.199023e+12    send(42)=4.398047e+12    send(43)=8.796093e+12
  send(44)=1.759219e+13    send(45)=3.518437e+13    send(46)=7.036874e+13    send(47)=1.407375e+14
  send(48)=2.814750e+14    send(49)=5.629500e+14    send(50)=1.125900e+15    send(51)=2.251800e+15
  send(52)=4.503600e+15    send(53)=9.007199e+15    send(54)=1.801440e+16    send(55)=3.602880e+16
  send(56)=7.205759e+16    send(57)=1.441152e+17    send(58)=2.882304e+17    send(59)=5.764608e+17
  send(60)=1.152922e+18    send(61)=2.305843e+18    send(62)=4.611686e+18    send(63)=9.223372e+18
  send(64)=1.844674e+19    send(65)=3.689349e+19    send(66)=7.378698e+19    send(67)=1.475740e+20
  send(68)=2.951479e+20    send(69)=5.902958e+20    send(70)=1.180592e+21    send(71)=2.361183e+21
  send(72)=4.722366e+21    send(73)=9.444733e+21    send(74)=1.888947e+22    send(75)=3.777893e+22
  send(76)=7.555786e+22    send(77)=1.511157e+23    send(78)=3.022315e+23    send(79)=6.044629e+23
  send(80)=1.208926e+24    send(81)=2.417852e+24    send(82)=4.835703e+24    send(83)=9.671407e+24
  send(84)=1.934281e+25    send(85)=3.868563e+25    send(86)=7.737125e+25    send(87)=1.547425e+26
  send(88)=3.094850e+26    send(89)=6.189700e+26    send(90)=1.237940e+27    send(91)=2.475880e+27
  send(92)=4.951760e+27    send(93)=9.903520e+27    send(94)=1.980704e+28    send(95)=3.961408e+28
  send(96)=7.922816e+28    send(97)=1.584563e+29    send(98)=3.169127e+29    send(99)=6.338253e+29
Hello World

 

0 Kudos
1 Solution
IanH
Honored Contributor II
1,205 Views

The issue is more than likely due to separate buffering of the output stream from the C++ function to the Fortran output.  The function may have completed execution, but information written to the stream may be buffered and not be written to the physical device straight away, in the meantime the Fortran program writes its output, so you see an apparent ordering change.  Buffering of streams is the sort of thing that changes when a language runtime figures out it is writing to a file rather than the console.

Try using the fflush C++ (and C) library function to flush stdout prior to returning to Fortran.

View solution in original post

0 Kudos
2 Replies
IanH
Honored Contributor II
1,206 Views

The issue is more than likely due to separate buffering of the output stream from the C++ function to the Fortran output.  The function may have completed execution, but information written to the stream may be buffered and not be written to the physical device straight away, in the meantime the Fortran program writes its output, so you see an apparent ordering change.  Buffering of streams is the sort of thing that changes when a language runtime figures out it is writing to a file rather than the console.

Try using the fflush C++ (and C) library function to flush stdout prior to returning to Fortran.

0 Kudos
MWind2
New Contributor III
1,205 Views
//fflush works.

#include <cstdio>
extern "C" int CPP_Library_Function(void* sendbuf, int sendcount, int *recvcounts) {
	for (int i = 0; i < sendcount; i++) {
		if (i > 0 && i % 4 == 0)printf("\n");
		printf("  send(%02d)=%e  ", i, *((float*)(sendbuf)+i));
	}
	fflush(stdout);
	return 0x11;
};

 

0 Kudos
Reply