Setlocale causes real number read error after calling gtk_init #42

Closed
bonanza opened this Issue Jun 21, 2012 · 35 comments

Comments

Projects
None yet
3 participants
Collaborator

bonanza commented Jun 21, 2012

with the current gtk-fortran revisions I get some strange behaviour with reading real numbers: after calling gtk_init all decimal places are set to zero.
Here is some short example, maybe you can test it on your systems:

program realtest

  use gtk, only: gtk_init

implicit none

  character(len=20)::line
  real::r
  
  line='100.3456'
  read(line,fmt=*)r
  print*,r

  call gtk_init ()

  read(line,fmt=*)r
  print*,r

end program realtest

The result on my system:

   100.34560    
   100.00000   

Any ideas?

Collaborator

jtappin commented Jun 21, 2012

No problems for me using either GTK 2.24.10 or 3.4.2 on Kubuntu 12.04. What system & versions do you have?

Collaborator

bonanza commented Jun 21, 2012

I have GTK 2.24.6 (which I use for the mentioned program) and GTK 3.5.4 running on Mint 12 with Linux 3.0.0-20.

Collaborator

jtappin commented Jun 21, 2012

I guess one thing to test to see where the problem is happening is to make the prints into:

print *, r, line

And how are you building the program? (e.g. do you have gtk-fortran installed as a library and then use the pgk-config script for the compile or do you explicitly link the object files?)

Collaborator

bonanza commented Jun 21, 2012

with GTK+3 (which produces the same strange result) I use e.g.
gfortran-4.6 realtest.f90 pkg-config --cflags --libs gtk+-3.0 -L. -lgtk-3-fortran -o realtest

Collaborator

bonanza commented Jun 21, 2012

using

print *,r,line 

I get

   100.34560     100.3456            
   100.00000     100.3456  
Collaborator

jtappin commented Jun 21, 2012

Really odd, the main difference I have is that I've built and installed gtk-fortran using the cmake build system, so I do:

gfortran real.f90 `pkg-config --cflags --libs gtk-2-fortran`

or

gfortran real.f90 `pkg-config --cflags --libs gtk-3-fortran`

And the output is:

100.34560     100.3456            
100.34560     100.3456            
Collaborator

bonanza commented Jun 28, 2012

I now tested on LMDE 201204 (Kernel 3.2.0-2-amd64, based on Debian Testing) with GTK 2.24.10 and GTK 3.2.3 using gfortran 4.6.3, latest gtk-fortran installed with cmake:

   100.34560     100.3456            
   100.00000     100.3456  

Imho it looks like the problem is related to gfortran. Which gfortran version you are using?

Collaborator

bonanza commented Jun 28, 2012

On Windows 7 64bit with GTK 2.24.10 and gfortran 4.7.0 I get the same problem !

Collaborator

bonanza commented Jun 28, 2012

Same problem on openSUSE 11.4 (x86_64, Linux 2.6.37.1-1.2-default) with GTK 2.22.1 and gfortran 4.5.1 20101208 [gcc-4_5-branch revision 167585]. Strange.

Collaborator

bonanza commented Jun 30, 2012

LMDE 201204 (Kernel 3.2.0-2-amd64, based on Debian Testing) with GTK 2.24.10 and GTK 3.2.3
using G95 (GCC 4.1.2 (g95 0.93!) Jun 16 2010):

g95 gtk.o realtest.f90 -o realtest `pkg-config --cflags --libs gtk+-2.0`

no problem! (except the remaining memory issue):

 100.3456 100.3456            
 100.3456 100.3456            
Remaining memory: 11 bytes at 00000000016d43f8 allocated at line 90 of gtk.f90
Collaborator

bonanza commented Jul 3, 2012

No problem with PathScale EKOPath Compiler Suite 1.0.0 on LMDE 201204 (Kernel 3.2.0-2-amd64, based on Debian Testing) with GTK 2.24.10 and GTK 3.2.3.

Collaborator

bonanza commented Jul 3, 2012

Also no problem with g95 0.93 on Windows 7 64bit with GTK 2.24.10, which confirms the assumption of a problem related to gfortran. Maybe a 64bit gfortran issue?

Collaborator

jtappin commented Jul 3, 2012

Very strange!

I've tried the code on a number of Linux versions (all using gfortran and [I think] all 64-bit) running under VirtualBox or on real hardware and have not yet found one where I can reproduce the problem.
There are also a variety of Gtk2 & 3 versions in there, and kernels ranging from 3.2 to 3.4.

Also, I have rpncalc running on all of the machines that I have (real & virtual) and that uses a read from a character variable to transfer the entry box contents to the stack and it works fine on all systems.

Collaborator

jtappin commented Jul 3, 2012

One possibly relevant thing I came across the other day is that the command line argument processing in gtk_init may not be 100% clean.

I was using the gdk-pixbuf routines to get png files into a Fortran program, and so wrote a wrapper for gdk_init as I didn't need gtk, but I found that after calling gdk_init, the pointers to the non-removed arguments could not be properly decoded by c_f_pointer, but I didn't have time to chase it any further.

Collaborator

bonanza commented Jul 3, 2012

Thanks for the hint, I'll try to follow this track ...
Maybe you can try to reproduce the problem with LMDE 201204 64bit (http://www.linuxmint.com/download_lmde.php) in a VM? For my failed tests I used a fresh installation of LMDE 201204 64bit.

Collaborator

jtappin commented Jul 4, 2012

LMDE works exactly as it ought to for me.

BTW: Were you actually able to build a usable system with Path64? Whenever I've tried to do anything with that it either fails to build or it won't compile anything.

Collaborator

bonanza commented Jul 4, 2012

Really strange! Next thing I'll try is running LMDE in a virtualbox.

With Path64 I get the base libraries compiled, but with gtk-hl-combobox.f90, gtk-hl-progress.f90, gtk-hl-spin-slider.f90, gtk-hl-dialog.f90 the following error occurs:

### Assertion failure at line 265 of /home/bonanza/pathscale-path64-suite-f0c0a45/compiler/compiler/src/crayf90/sgi/cwh_stk.cxx:
### Compiler Error in file gtk-hl-progress.f90 during IR->WHIRL Conversion phase:
###  TOS is not ADDR
Signal: Aborted in IR->WHIRL Conversion phase.
"gtk-hl-progress.f90": Error: Signal Aborted in phase IR->WHIRL Conversion -- processing aborted
*** Internal stack backtrace:
    /opt/ekopath/1.0.0/lib/1.0.0/x8664/mfef95() [0x584c8d]
    /opt/ekopath/1.0.0/lib/1.0.0/x8664/mfef95() [0x584d17]
    /opt/ekopath/1.0.0/lib/1.0.0/x8664/mfef95() [0x5863b0]
    /opt/ekopath/1.0.0/lib/1.0.0/x8664/mfef95(ErrMsg_Report+0x4e) [0x586492]
    /opt/ekopath/1.0.0/lib/1.0.0/x8664/mfef95(ErrMsgLine+0xa5) [0x586600]
    /opt/ekopath/1.0.0/lib/1.0.0/x8664/mfef95() [0x58430e]
    /lib/x86_64-linux-gnu/libc.so.6(+0x324f0) [0x2b574ed274f0]
    /lib/x86_64-linux-gnu/libc.so.6(gsignal+0x35) [0x2b574ed27475]
    /lib/x86_64-linux-gnu/libc.so.6(abort+0x180) [0x2b574ed2a6f0]
    /opt/ekopath/1.0.0/lib/1.0.0/x8664/mfef95(Fatal_Error+0) [0x58697a]
    /opt/ekopath/1.0.0/lib/1.0.0/x8664/mfef95(_Z16cwh_stk_pop_ADDRv+0x72) [0x5788c0]
    /opt/ekopath/1.0.0/lib/1.0.0/x8664/mfef95(_Z20cwh_stmt_call_helperimil+0xee) [0x570172]
    /opt/ekopath/1.0.0/lib/1.0.0/x8664/mfef95(fei_call+0x3d) [0x570f67]
    /opt/ekopath/1.0.0/lib/1.0.0/x8664/mfef95() [0x96ba55]
    /opt/ekopath/1.0.0/lib/1.0.0/x8664/mfef95() [0x97718a]
    /opt/ekopath/1.0.0/lib/1.0.0/x8664/mfef95() [0x954e7d]
    /opt/ekopath/1.0.0/lib/1.0.0/x8664/mfef95() [0x954740]
    /opt/ekopath/1.0.0/lib/1.0.0/x8664/mfef95(cvrt_to_pdg+0x46e) [0x95408b]
    /opt/ekopath/1.0.0/lib/1.0.0/x8664/mfef95(main+0x66b) [0x5b713f]
    /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd) [0x2b574ed13ead]
    /opt/ekopath/1.0.0/lib/1.0.0/x8664/mfef95() [0x4a6999]
pathf95 ERROR: execute '/opt/ekopath/1.0.0/lib/1.0.0/x8664/mfef95' failed: Died due to unknown signal

Furthermore, gtk-hl-tree.f90, gtk-hl-chooser.f90 and gtk_draw_hl as well as all examples (except gtkbuilder2.f90!) produce illegal argument errors in c_funloc:

module gtk_hl_tree
       ^           
pathf95-855 pathf95: ERROR GTK_HL_TREE, File = gtk-hl-tree.f90, Line = 35, Column = 8 
  The compiler has detected errors in module "GTK_HL_TREE".  No module information file will be created for this module.

                     & c_funloc(hl_gtk_listn_edit_cb))
                       ^                               
pathf95-700 pathf95: ERROR HL_GTK_LISTN_NEW, File = gtk-hl-tree.f90, Line = 279, Column = 24 
  The intrinsic call "C_FUNLOC" is being made with illegal arguments.

    call g_list_foreach(slist, c_funloc(gtk_tree_path_free), C_NULL_PTR)
                               ^                                         
pathf95-700 pathf95: ERROR HL_GTK_LISTN_GET_SELECTIONS, File = gtk-hl-tree.f90, Line = 493, Column = 32 
  The intrinsic call "C_FUNLOC" is being made with illegal arguments.

                     & c_funloc(hl_gtk_tree_edit_cb))
                       ^                              
pathf95-700 pathf95: ERROR HL_GTK_TREE_NEW, File = gtk-hl-tree.f90, Line = 1679, Column = 24 
  The intrinsic call "C_FUNLOC" is being made with illegal arguments.

    call g_list_foreach(slist, c_funloc(gtk_tree_path_free), C_NULL_PTR)
                               ^                                         
pathf95-700 pathf95: ERROR HL_GTK_TREE_GET_SELECTIONS, File = gtk-hl-tree.f90, Line = 2069, Column = 32 
  The intrinsic call "C_FUNLOC" is being made with illegal arguments.

pathf95: PathScale(TM) Fortran Version 1.0.0 (f14) Wed Jul  4, 2012  07:43:30
pathf95: 2641 source lines
pathf95: 5 Error(s), 0 Warning(s), 0 Other message(s), 0 ANSI(s)
pathf95: "explain pathf95-message number" gives more information about each message

module gtk_hl_chooser
       ^              
pathf95-855 pathf95: ERROR GTK_HL_CHOOSER, File = gtk-hl-chooser.f90, Line = 35, Column = 8 
  The compiler has detected errors in module "GTK_HL_CHOOSER".  No module information file will be created for this module.

               & hl_gtk_entry_new(activate=c_funloc(hl_gtk_chooser_filt_cb), &
                                           ^                                   
pathf95-700 pathf95: ERROR HL_GTK_FILE_CHOOSER_SHOW, File = gtk-hl-chooser.f90, Line = 466, Column = 44 
  The intrinsic call "C_FUNLOC" is being made with illegal arguments.

               & clicked=c_funloc(hl_gtk_chooser_filt_cb), &
                         ^                                   
pathf95-700 pathf95: ERROR HL_GTK_FILE_CHOOSER_SHOW, File = gtk-hl-chooser.f90, Line = 471, Column = 26 
  The intrinsic call "C_FUNLOC" is being made with illegal arguments.

         & c_funloc(hl_gtk_chooser_resp_cb), c_loc(chooser_info))
           ^                                                      
pathf95-700 pathf95: ERROR HL_GTK_FILE_CHOOSER_SHOW, File = gtk-hl-chooser.f90, Line = 479, Column = 12 
  The intrinsic call "C_FUNLOC" is being made with illegal arguments.

pathf95: PathScale(TM) Fortran Version 1.0.0 (f14) Wed Jul  4, 2012  07:43:30
pathf95: 600 source lines
pathf95: 4 Error(s), 0 Warning(s), 0 Other message(s), 0 ANSI(s)

module gtk_draw_hl
       ^           
pathf95-855 pathf95: ERROR GTK_DRAW_HL, File = gtk-draw-hl.f90, Line = 36, Column = 8 
  The compiler has detected errors in module "GTK_DRAW_HL".  No module information file will be created for this module.

            & c_funloc(hl_gtk_drawing_area_destroy_cb))
              ^                                         
pathf95-700 pathf95: ERROR HL_GTK_DRAWING_AREA_NEW, File = gtk-draw-hl.f90, Line = 271, Column = 15 
  The intrinsic call "C_FUNLOC" is being made with illegal arguments.

            & c_funloc(hl_gtk_drawing_area_expose_cb))
              ^                                        
pathf95-700 pathf95: ERROR HL_GTK_DRAWING_AREA_NEW, File = gtk-draw-hl.f90, Line = 284, Column = 15 
  The intrinsic call "C_FUNLOC" is being made with illegal arguments.

pathf95: PathScale(TM) Fortran Version 1.0.0 (f14) Wed Jul  4, 2012  07:43:30
pathf95: 586 source lines
pathf95: 3 Error(s), 0 Warning(s), 0 Other message(s), 0 ANSI(s)
Collaborator

bonanza commented Jul 4, 2012

I did a fresh install of LMDE 201204 64bit, added gfortran-4.6, git and gtk+-2-dev in a VM (VirtualBox). After running

GFC=gfortran-4.6 ./test.sh

I compiled realtest.f90:

gfortran-4.6 gtk.o realtest.f90 -o realtest `pkg-config --cflags --libs gtk+-2.0`

and got the problem reproduced that way.
A snapshot of my VM you can find here: http://sonne.cpfs.mpg.de:8080/gtk-fortran/LMDE-201204-64bit_gtkfortran.ova

Collaborator

jtappin commented Jul 4, 2012

Ah yes, now I recall. The implementation of c_funloc in the path64 compiler is pretty useless. I think I did complain about it in their issues section but nothing was done.

Here is a version that uses gdk_init:

program realtest

  use gdk, only: gdk_init
  use iso_c_binding

  implicit none

  character(len=20)::line
  real::r
  type(c_ptr), allocatable, target :: argv(:)
  integer(kind=c_int), target :: argc

  line='100.3456'
  read(line,fmt=*)r
  print*,r

  argc = getargs(argv)
  read(line,fmt=*)r
  print*,r
  call gdk_init (c_loc(argc), c_loc(argv))

  read(line,fmt=*)r
  print*,r

contains
  function getargs(argv) result(argc)
    type(c_ptr), allocatable :: argv(:)
    integer(kind=c_int) :: argc
    character(len=256,kind=c_char) :: arg
    character(len=1,kind=c_char), dimension(:),pointer :: carg
    integer :: i, j, strlen

    argc = command_argument_count()
    allocate(argv(0:argc))

    do i = 0, argc
       call get_command_argument (i,arg,strlen)
       allocate(carg(0:strlen))
       do j = 0, strlen-1
          carg(j) = arg(j+1:j+1)
       end do
       carg(strlen) = c_null_char
       argv(i) = c_loc (carg(0))
    end do
    argc = argc + 1
  end function getargs

end program realtest

Works as expected on my main system.

Collaborator

bonanza commented Jul 4, 2012

Works also as expected on my problematic linux-gfortran system. Hmmm.

Collaborator

bonanza commented Jul 5, 2012

Another interesting fact:
If I just move the gtk_init_real subroutine in gtk.f90 from the interface block to the module block:

module gtk
  !use iso_c_binding, only: c_null_char, c_null_ptr, c_null_funptr, c_ptr, c_funptr, c_char, c_int, c_long
  use iso_c_binding
  implicit none
  include "gtkenums-auto.f90"

  interface
    !**************************************************************************
    ! You can add your own additional interfaces here:
    !**************************************************************************

    !**************************************************************************
    ! The interfaces automatically generated by cfwrapper.py are included here.
    ! Do not modify.
    include "gtk-auto.f90"
    !**************************************************************************
  end interface 

  ! Some useful parameters to ease coding:
!  character(kind=c_char), parameter :: CNULL = c_null_char
!  type(c_ptr), parameter       :: NULL = c_null_ptr
!  type(c_funptr), parameter    :: FNULL = c_null_funptr
  ! In GTK+ gboolean is int:
  integer(c_int), parameter   :: FALSE = 0
  integer(c_int), parameter   :: TRUE = 1

contains
  subroutine g_signal_connect (instance, detailed_signal, c_handler, data0)
    use iso_c_binding, only: c_ptr, c_char, c_funptr
    use g, only: g_signal_connect_data
    character(kind=c_char):: detailed_signal(*)
    type(c_ptr)      :: instance
    type(c_funptr)   :: c_handler
    type(c_ptr), optional :: data0
    integer(c_long) :: handler_id

    if (present(data0)) then
      handler_id =  g_signal_connect_data (instance, detailed_signal, c_handler, &
            & data0, c_null_funptr, 0)
    else
      handler_id =  g_signal_connect_data (instance, detailed_signal, c_handler, &
            & c_null_ptr, c_null_funptr, 0)
    end if
  end subroutine

  subroutine gtk_init_real(argc,argv) bind(c,name='gtk_init')
    use iso_c_binding, only: c_int, c_ptr
    integer(c_int) :: argc
    type(c_ptr)    :: argv
  end subroutine 

  subroutine gtk_init()
    use iso_c_binding, only: c_ptr, c_char, c_int, c_null_char, c_loc
    character(len=256,kind=c_char) :: arg
    character(len=1,kind=c_char), dimension(:),pointer :: carg
    type(c_ptr), allocatable, target :: argv(:)
    integer(c_int) :: argc, strlen, i, j

    argc = command_argument_count()
    allocate(argv(0:argc))

    do i = 0, argc
      call get_command_argument (i,arg,strlen)
      allocate(carg(0:strlen))
      do j = 0, strlen-1
        carg(j) = arg(j+1:j+1)
      end do
      carg(strlen) = c_null_char
      argv(i) = c_loc (carg(0))
    end do

    argc = argc + 1
    call gtk_init_real (argc, c_loc(argv))
    !deallocate(argv)
    !deallocate(carg)
  end subroutine gtk_init

end module gtk

I get no problem with "realtest".
But this produces runtime errors in the examples, e.g.:

GLib-GObject-CRITICAL **: /tmp/buildd/glib2.0-2.30.2/./gobject/gtype.c:2715: You forgot to call g_type_init()
(process:5269): GLib-CRITICAL **: g_once_init_leave: assertion `initialization_value != 0' failed
Collaborator

jtappin commented Jul 5, 2012

That's pretty much what I'd expect.

By moving gtk_init_real to the module body, you are converting it from an interface telling Fortran how to call the C routine in libgtk, into a "do-nothing" subroutine. I'm not quite sure what the name= clause will do in that context but I think it would mean that to call gtk_init_real from C you would use gtk_init. Thus when you try to call any Gtk (or other related library) routines in the examples, they will fail because Gtk has not been initialized.

One thing that might be worth trying would be to take the Gdk example and replace gdk_init with gtk_init_real (I think that c_loc(argc) should be replaced by plain argc as in the gtk_init routine.

Collaborator

bonanza commented Jul 5, 2012

Replacement of gdk_init with gtk_init_real and c_loc(argc) with argc in the gdk example reproduces the problem:

   100.34560    
   100.34560    
   100.00000  
Collaborator

jtappin commented Jul 5, 2012

I really don't understand what might be going on here. The fact that you are able to get the problem in a consistent way while I've yet to reproduce it is odd. (I've not been able to test the VM image as it doesn't have autologin configured and the most obvious guesses for user and password didn't work).

I think the following version of gtk.f90 might be better anyway (it is doing what gtk_init() does internally and avoids a possible C/Fortran i/o conflict):

! Copyright (C) 2011
! Free Software Foundation, Inc.

! This file is part of the gtk-fortran GTK+ Fortran Interface library.

! This is free software; you can redistribute it and/or modify
! it under the terms of the GNU General Public License as published by
! the Free Software Foundation; either version 3, or (at your option)
! any later version.

! This software is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
! GNU General Public License for more details.

! Under Section 7 of GPL version 3, you are granted additional
! permissions described in the GCC Runtime Library Exception, version
! 3.1, as published by the Free Software Foundation.

! You should have received a copy of the GNU General Public License along with
! this program; see the files COPYING3 and COPYING.RUNTIME respectively.
! If not, see <http://www.gnu.org/licenses/>.
!
! Contributed by Vincent Magnin, Jerry DeLisle, "jtappin" and Tobias Burnus, 01-23-2011
! Last modification: 03-15-2011

module gtk
  !use iso_c_binding, only: c_null_char, c_null_ptr, c_null_funptr, c_ptr, c_funptr, c_char, c_int, c_long
  use iso_c_binding
  implicit none
  include "gtkenums-auto.f90"

  interface
    !**************************************************************************
    ! You can add your own additional interfaces here:
    !**************************************************************************
!!$    subroutine gtk_init_real(argc,argv) bind(c,name='gtk_init')
!!$      use iso_c_binding, only: c_int, c_ptr
!!$      integer(c_int) :: argc
!!$      type(c_ptr)    :: argv
!!$    end subroutine 

    !**************************************************************************
    ! The interfaces automatically generated by cfwrapper.py are included here.
    ! Do not modify.
    include "gtk-auto.f90"
    !**************************************************************************
  end interface 

  ! Some useful parameters to ease coding:
!  character(kind=c_char), parameter :: CNULL = c_null_char
!  type(c_ptr), parameter       :: NULL = c_null_ptr
!  type(c_funptr), parameter    :: FNULL = c_null_funptr
  ! In GTK+ gboolean is int:
  integer(c_int), parameter   :: FALSE = 0
  integer(c_int), parameter   :: TRUE = 1

contains
  subroutine g_signal_connect (instance, detailed_signal, c_handler, data0)
    use iso_c_binding, only: c_ptr, c_char, c_funptr
    use g, only: g_signal_connect_data
    character(kind=c_char):: detailed_signal(*)
    type(c_ptr)      :: instance
    type(c_funptr)   :: c_handler
    type(c_ptr), optional :: data0
    integer(c_long) :: handler_id

    if (present(data0)) then
      handler_id =  g_signal_connect_data (instance, detailed_signal, c_handler, &
            & data0, c_null_funptr, 0)
    else
      handler_id =  g_signal_connect_data (instance, detailed_signal, c_handler, &
            & c_null_ptr, c_null_funptr, 0)
    end if
  end subroutine


  subroutine gtk_init()
    use iso_c_binding, only: c_ptr, c_char, c_int, c_null_char, c_loc
    character(len=256,kind=c_char) :: arg
    character(len=1,kind=c_char), dimension(:),pointer :: carg
    type(c_ptr), allocatable, target :: argv(:)
    integer(c_int) :: argc, strlen, i, j

    argc = command_argument_count()
    allocate(argv(0:argc))

    do i = 0, argc
      call get_command_argument (i,arg,strlen)
      allocate(carg(0:strlen))
      do j = 0, strlen-1
        carg(j) = arg(j+1:j+1)
      end do
      carg(strlen) = c_null_char
      argv(i) = c_loc (carg(0))
    end do

    argc = argc + 1
    if (gtk_init_check(c_loc(argc), c_loc(argv)) /= TRUE) then
       print *, "Gtk+ initialization failed"
       stop
    end if
    !deallocate(argv)
    !deallocate(carg)
  end subroutine gtk_init

end module gtk
Collaborator

bonanza commented Jul 5, 2012

I forgot to give the login for the VM, sorry.
Here is it:
user: test
pw: test
... is not obvious enough ;-)

Collaborator

bonanza commented Jul 5, 2012

The problem is not directly related to gtk_init, e.g. also gtk_set_locale reproduces the problem:

program realtest2

  use gtk
  use iso_c_binding

  implicit none

  character(len=10)::line
  real::r
  type(c_ptr)::locale

  line='100.3456'
  read(line,fmt=*)r
  print*,r

  locale=gtk_set_locale ()

  read(line,fmt=*)r
  print*,r

end program realtest2

gives the result

   100.34560    
   100.00000    
Collaborator

bonanza commented Jul 5, 2012

With your gtk.f90 version I get:

gtk.f90:99.29:

    if (gtk_init_check(c_loc(argc), c_loc(argv)) /= TRUE) then
                             1
Error: Parameter 'argc' to 'c_loc' at (1) must be either a TARGET or an associated pointer
Collaborator

jtappin commented Jul 5, 2012

Sorry, just change the declaration

integer(c_int) :: argc, strlen, i, j

to

integer(c_int), target :: argc
integer(c_int) :: strlen, i, j
Collaborator

bonanza commented Jul 5, 2012

I did it, but got the real-problem again with this gtk.f90 version.

Collaborator

jtappin commented Jul 5, 2012

I'm starting to think the real culprit is gtk_set_locale as 'gtk_init' does call it somewhere about where I gave up on the source code of Gtk+.

Try adding:

call gtk_disable_setlocale()

before the call to gtk_init (either inside gtk.f90 or in your test program).

Collaborator

jtappin commented Jul 5, 2012

Oh, and one other thing to try would be (on a virtual machine) to set the locale to English (US) (I assume you are currently using German). When I get home I'll try the reverse process.

Collaborator

bonanza commented Jul 5, 2012

I changed the locale to en_US.UTF-8 and the problem is gone!
However, gtk_disable_setlocale() don't eliminate the problem.

Collaborator

jtappin commented Jul 5, 2012

I think I understand what might be happening.

  1. When gtk_init or gtk_set_locale sets the German locale, that includes setting the decimal separator to ",".
  2. gfortran's read from an internal file (character variable) then honours that setting (even though standard output is still using "." possibly because it was opened before the locale was set).
  3. The other Fortran compilers are not affected because they are not as closely linked to gcc which was used to build Gtk+.

If this hypothesis is correct then (assuming that Metcalfe et al. "Fortran 95/2003 explained" is definitive) it is a bug in gfortran because they say in the discussion of decimal point vs. decimal comma that the default is decimal="point" not that it depends on the selected locale (p 315-6).

Collaborator

bonanza commented Jul 5, 2012

I was wrong in my previous comment because I confused my test files. Sorry. Actually, gtk_disable_setlocale() works to prevent the problem. However, as I can also read from http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36857 the locale setting should not influence the default float handling of gfortran. Imho it looks like another missing sanity check in gfortran. Maybe we should include the call of gtk_disable_setlocale() from gtk_init in gtk.f90 for now.

@bonanza bonanza closed this Jul 5, 2012

@jtappin jtappin reopened this Jul 6, 2012

Collaborator

jtappin commented Jul 6, 2012

Just an (I hope) final summary.

  • The issue is with the interaction of the gfortran runtime and setlocale.
  • For locales in which the decimal separator is a comma, after setlocale is called, a point is not interpreted as a decimal by the decoding routines (at least for list-directed reads). It appears that the separators are processed by a different piece of the runtime and so a value written with a comma as a decimal separator in an internal file or an external file opened with defaults is treated as 2 comma separated values.
  • As a result after setlocale is called from a Fortran program in a locale with comma as the decimal separator, real numbers with decimals cannot be read from a default list-directed input in any way.

As a workaround I have added a call to gtk_disable_setlocale to gtk_init in gtk.f90. This of course disables localization in gtk (and friends), but that seems better than having broken read behaviour across most of Europe and South America.

If you really need localization, then use gtk_init_check, but you will need to extract the command line arguments manually.

I have added a comment describing the case to http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47007.

@vmagnin vmagnin closed this Feb 17, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment