----- Original Message -----
> 
> 
> ----- Original Message -----
> > The gcc reponse to this problem is "not a bug" since the standard requires
> > len=1 as the only valid thing for type c_char in the iso_c_binding
> > The FORTRAN group response is that gcc has had a bug allowing len>1 since
> > this has been true since FORTRAN 2003.
> > 
> > So...unless we put pressure on gcc to maintain backwards compatibility our
> > shared data structure is going to need to be modified to some crazy thing
> > to
> > copy char arrays around....
> > 
> > Thoughts?
> > 
> > de Mike W9MDB
> > 
> Thanks for info, so that's what I was afraid about - it exploited / relied
> upon
> undocumented GNU specific bug / feature.
> 
> I think gfortran should have something like -std=gnuf2003 for full backward
> compatibility like gcc has. But the correct thing to do is not to rely
> on GNU specific behavior and fix the code to be according to the standard.
> 
> I think two wrapper functions to copy strings in/out should do it. I think
> the performance overhead to copy few bytes shouldn't cause any visible
> performance impact. At the moment I have no better idea how to quickly
> fix it
> 
> thanks & regards
> 
> Jaroslav, OK2JRQ
> 

Attached is proposed fix that allowed me to compile wsjtx with gcc-8.0.1.
It's backward compatible and the compilation also works with gcc-7.3.1.
Unfortunately, I didn't have my rig handy, so I did only simple unit
testing. Maybe there are problems, but the basic idea should be clear
from the patch. Feel free too comment.

In addition to Fortran fixes and introduction of the strconvert_module
I also had to add one more include for the gcc to be happy.

I also noticed that the C interface has small storage for the string,
e.g. for the mygrid it requires 6 characters + NULL, i.e. 7 characters
storage space. I increased the storage space accordingly.

Moreover I noticed and fixed typo in the jt9.f90 initialization code
which initialized hiscall instead of the hisgrid to the "EN37"

thanks & regards

Jaroslav, OK2JRQ
From a156e03a9d08c83d2a8b61fff7a984f670c61e31 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20=C5=A0karvada?= <[email protected]>
Date: Fri, 16 Mar 2018 15:00:04 +0100
Subject: [PATCH] Fixed compilation with gcc/gfortran-8.0.1
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Jaroslav Å karvada <[email protected]>
---
 wsjtx/CMakeLists.txt            |  1 +
 wsjtx/commons.h                 | 10 +++++-----
 wsjtx/lib/Makefile.linux        |  2 +-
 wsjtx/lib/decoder.f90           | 37 ++++++++++++++++++++++++-------------
 wsjtx/lib/jt9.f90               | 15 ++++++++-------
 wsjtx/lib/jt9com.f90            | 10 +++++-----
 wsjtx/lib/strconvert_module.f90 | 37 +++++++++++++++++++++++++++++++++++++
 wsjtx/wsjtx_config.h.in         |  1 +
 8 files changed, 82 insertions(+), 31 deletions(-)
 create mode 100644 wsjtx/lib/strconvert_module.f90

diff --git a/wsjtx/CMakeLists.txt b/wsjtx/CMakeLists.txt
index e0ccd51..b37453d 100644
--- a/wsjtx/CMakeLists.txt
+++ b/wsjtx/CMakeLists.txt
@@ -351,6 +351,7 @@ set (wsjt_FSRCS
   lib/timer_impl.f90
   lib/timer_module.f90
   lib/wavhdr.f90
+  lib/strconvert_module.f90
 
   # remaining non-module sources
   lib/addit.f90
diff --git a/wsjtx/commons.h b/wsjtx/commons.h
index 7c202d2..e5bdd2d 100644
--- a/wsjtx/commons.h
+++ b/wsjtx/commons.h
@@ -59,11 +59,11 @@ extern struct dec_data {
     int naggressive;
     bool nrobust;
     int nexp_decode;
-    char datetime[20];
-    char mycall[12];
-    char mygrid[6];
-    char hiscall[12];
-    char hisgrid[6];
+    char datetime[21];
+    char mycall[13];
+    char mygrid[7];
+    char hiscall[13];
+    char hisgrid[7];
   } params;
 } dec_data;
 
diff --git a/wsjtx/lib/Makefile.linux b/wsjtx/lib/Makefile.linux
index 14bc077..ea56b42 100644
--- a/wsjtx/lib/Makefile.linux
+++ b/wsjtx/lib/Makefile.linux
@@ -39,7 +39,7 @@ OBJS1 = astrosub.o astro0.o astro.o tm2.o sun.o moondop.o coord.o tmoonsub.o \
 	symspec.o analytic.o db.o genjt9.o jt9fano.o \
 	packbits.o unpackbits.o encode232.o interleave9.o \
 	entail.o fano232.o gran.o sync9.o decjt9.o \
-	fil3.o decoder.o grid2n.o n2grid.o timer.o \
+	fil3.o strconvert_module.o decoder.o grid2n.o n2grid.o timer.o \
 	softsym.o peakdt9.o getlags.o afc9.o fchisq.o \
 	twkfreq.o downsam9.o symspec2.o ipcomm.o sleep_msec.o \
 	stdmsg.o sec_midn.o usleep.o azdist.o geodist.o morse.o \
diff --git a/wsjtx/lib/decoder.f90 b/wsjtx/lib/decoder.f90
index 2035703..54ef31b 100644
--- a/wsjtx/lib/decoder.f90
+++ b/wsjtx/lib/decoder.f90
@@ -3,6 +3,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
   !$ use omp_lib
   use prog_args
   use timer_module, only: timer
+  use strconvert_module
   use jt4_decode
   use jt65_decode
   use jt9_decode
@@ -11,6 +12,11 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
   include 'jt9com.f90'
   include 'timer_common.inc'
 
+  character*12 :: mycall
+  character*6 :: mygrid
+  character*12 :: hiscall
+  character*6 :: hisgrid
+
   type, extends(jt4_decoder) :: counting_jt4_decoder
      integer :: decoded
   end type counting_jt4_decoder
@@ -38,6 +44,11 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
   type(counting_jt9_decoder) :: my_jt9
   type(counting_ft8_decoder) :: my_ft8
 
+  call str_c2f(params%mycall, mycall)
+  call str_c2f(params%mygrid, mygrid)
+  call str_c2f(params%hiscall, hiscall)
+  call str_c2f(params%hisgrid, hisgrid)
+
   ! initialize decode counts
   my_jt4%decoded = 0
   my_jt65%decoded = 0
@@ -49,7 +60,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
   if(mod(params%nranera,2).eq.0) ntrials=10**(params%nranera/2)
   if(mod(params%nranera,2).eq.1) ntrials=3*10**(params%nranera/2)
   if(params%nranera.eq.0) ntrials=0
-  
+
   nfail=0
 10 if (params%nagain) then
      open(13,file=trim(temp_dir)//'/decoded.txt',status='unknown',            &
@@ -77,7 +88,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
           params%nftx,newdat,params%nutc,params%nfa,params%nfb,              &
           params%nexp_decode,params%ndepth,logical(params%nagain),           &
           logical(params%lft8apon),logical(params%lapcqonly),params%napwid,  &
-          params%mycall,params%mygrid,params%hiscall,params%hisgrid)
+          mycall,mygrid,hiscall,hisgrid)
      call timer('decft8  ',1)
      if(nfox.gt.0) then
         n30min=minval(n30fox(1:nfox))
@@ -99,7 +110,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
               nfreqfox(j)=nfreqfox(i)
               n30fox(j)=n
               m=n30max-n
-              call azdist(params%mygrid,g2fox(j),0.d0,nAz,nEl,nDmiles,nDkm,  &
+              call azdist(mygrid,g2fox(j),0.d0,nAz,nEl,nDmiles,nDkm,  &
                    nHotAz,nHotABetter)
               write(19,1004) c2fox(j),g2fox(j),nsnrfox(j),nfreqfox(j),nDkm,m
 1004          format(a12,1x,a4,i5,i6,i7,i3)
@@ -151,8 +162,8 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
      call my_jt4%decode(jt4_decoded,dd,jz,params%nutc,params%nfqso,         &
           params%ntol,params%emedelay,params%dttol,logical(params%nagain),  &
           params%ndepth,logical(params%nclearave),params%minsync,           &
-          params%minw,params%nsubmode,params%mycall,params%hiscall,         &
-          params%hisgrid,params%nlist,params%listutc,jt4_average)
+          params%minw,params%nsubmode,mycall,hiscall,                       &
+          hisgrid,params%nlist,params%listutc,jt4_average)
      go to 800
   endif
 
@@ -184,8 +195,8 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
           nf1,nf2,params%nfqso,ntol65,params%nsubmode,params%minsync,      &
           logical(params%nagain),params%n2pass,logical(params%nrobust),    &
           ntrials,params%naggressive,params%ndepth,params%emedelay,        &
-          logical(params%nclearave),params%mycall,params%hiscall,          &
-          params%hisgrid,params%nexp_decode,params%nQSOProgress,           &
+          logical(params%nclearave),mycall,hiscall,                        &
+          hisgrid,params%nexp_decode,params%nQSOProgress,                  &
           logical(params%ljt65apon))
      call timer('jt65a   ',1)
 
@@ -210,8 +221,8 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
              nf1,nf2,params%nfqso,ntol65,params%nsubmode,params%minsync,   &
              logical(params%nagain),params%n2pass,logical(params%nrobust), &
              ntrials,params%naggressive,params%ndepth,params%emedelay,     &
-             logical(params%nclearave),params%mycall,params%hiscall,       &
-             params%hisgrid,params%nexp_decode,params%nQSOProgress,        &
+             logical(params%nclearave),mycall,hiscall,                     &
+             hisgrid,params%nexp_decode,params%nQSOProgress,               &
              logical(params%ljt65apon))
         call timer('jt65a   ',1)
      else
@@ -489,10 +500,10 @@ contains
        c1=decoded0(1:i1-1)//'            '
        c2=decoded0(i1+1:i2-1)
        g2=decoded0(i2+1:i3-1)
-       b0=c1.eq.params%mycall
-       if(len(trim(c1)).ne.len(trim(params%mycall))) then
-          i4=index(trim(c1),trim(params%mycall))
-          i5=index(trim(params%mycall),trim(c1))
+       b0=c1.eq.mycall
+       if(len(trim(c1)).ne.len(trim(mycall))) then
+          i4=index(trim(c1),trim(mycall))
+          i5=index(trim(mycall),trim(c1))
           if(i4.ge.1 .or. i5.ge.1) b0=.true.
        endif
        b1=i3-i2.eq.5 .and. isgrid4(g2)
diff --git a/wsjtx/lib/jt9.f90 b/wsjtx/lib/jt9.f90
index 7849726..4c0225c 100644
--- a/wsjtx/lib/jt9.f90
+++ b/wsjtx/lib/jt9.f90
@@ -8,6 +8,7 @@ program jt9
   use, intrinsic :: iso_c_binding
   use FFTW3
   use timer_module, only: timer
+  use strconvert_module
   use timer_impl, only: init_timer, fini_timer
   use readwav
 
@@ -278,13 +279,13 @@ program jt9
      shared_data%params%nranera=6                      !### ntrials=3000
      shared_data%params%nrobust=.false.
      shared_data%params%nexp_decode=nexp_decode
-     shared_data%params%mycall=mycall
-     shared_data%params%mygrid=mygrid
-     shared_data%params%hiscall=hiscall
-     shared_data%params%hisgrid=hisgrid
-     if (shared_data%params%mycall == '') shared_data%params%mycall='K1ABC'
-     if (shared_data%params%hiscall == '') shared_data%params%hiscall='W9XYZ'
-     if (shared_data%params%hisgrid == '') shared_data%params%hiscall='EN37'
+     if (mycall == '') mycall='K1ABC'
+     if (hiscall == '') hiscall='W9XYZ'
+     if (hisgrid == '') hisgrid='EN37'
+     call str_f2c(mycall, shared_data%params%mycall)
+     call str_f2c(mygrid, shared_data%params%mygrid)
+     call str_f2c(hiscall, shared_data%params%hiscall)
+     call str_f2c(hisgrid, shared_data%params%hisgrid)
      if (tx9) then
         shared_data%params%ntxmode=9
      else
diff --git a/wsjtx/lib/jt9com.f90 b/wsjtx/lib/jt9com.f90
index be44f3b..c595582 100644
--- a/wsjtx/lib/jt9com.f90
+++ b/wsjtx/lib/jt9com.f90
@@ -41,11 +41,11 @@
      integer(c_int) :: naggressive
      logical(c_bool) :: nrobust
      integer(c_int) :: nexp_decode
-     character(kind=c_char, len=20) :: datetime
-     character(kind=c_char, len=12) :: mycall
-     character(kind=c_char, len=6) :: mygrid
-     character(kind=c_char, len=12) :: hiscall
-     character(kind=c_char, len=6) :: hisgrid
+     character(kind=c_char) :: datetime(20)
+     character(kind=c_char) :: mycall(12)
+     character(kind=c_char) :: mygrid(6)
+     character(kind=c_char) :: hiscall(12)
+     character(kind=c_char) :: hisgrid(6)
   end type params_block
 
   type, bind(C) :: dec_data
diff --git a/wsjtx/lib/strconvert_module.f90 b/wsjtx/lib/strconvert_module.f90
new file mode 100644
index 0000000..50b21b5
--- /dev/null
+++ b/wsjtx/lib/strconvert_module.f90
@@ -0,0 +1,37 @@
+module strconvert_module
+  implicit none
+
+  public :: str_f2c, str_c2f
+
+contains
+  subroutine str_f2c(str_f, str_c)
+    use, intrinsic :: iso_c_binding, only: c_char, c_null_char
+    implicit none
+    character(len=*), intent(in) :: str_f
+    character(kind=c_char), bind(C), intent(out) :: str_c(*)
+    integer :: i
+
+    do i = 1, len_trim(str_f)
+      str_c(i) = str_f(i:i + 1)
+    end do
+    str_c(i) = c_null_char
+  end subroutine str_f2c
+
+  subroutine str_c2f(str_c, str_f)
+    use, intrinsic :: iso_c_binding, only: c_char, c_null_char
+    implicit none
+    character(kind=c_char), bind(C), intent(in) :: str_c(*)
+    character(len=*), intent(out) :: str_f
+    integer :: i
+
+    str_f = ""
+    i = 1
+    do
+      if (str_c(i) == c_null_char) then
+        return
+      endif
+      str_f = trim(str_f) // trim(str_c(i))
+      i = i + 1
+    end do
+  end subroutine str_c2f
+end module strconvert_module
diff --git a/wsjtx/wsjtx_config.h.in b/wsjtx/wsjtx_config.h.in
index 80ac160..599038a 100644
--- a/wsjtx/wsjtx_config.h.in
+++ b/wsjtx/wsjtx_config.h.in
@@ -44,6 +44,7 @@ extern "C"  {
 
   /* typedef for consistent gfortran ABI for charlen type hidden arguments */
 #if __GNUC__ > 7
+#include <stddef.h>
   typedef size_t fortran_charlen_t;
 #else
   typedef int fortran_charlen_t;
-- 
2.13.6

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
wsjt-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/wsjt-devel

Reply via email to