This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gfortran] I/O of large integer and real kinds, round 2


Attached patch (one diff, one new configuration script and two testcases and the ChangeLog) enables I/O of large integer and real kinds. Right now,
it includes integer(16), real(10) and real(16), but it is easy to add
other types afterwards if need be since the mechanism is now very general.

Built, tested and regtested on: - i686-linux, which has real(10) - i386-freebsd - sparc-solaris, which has real(16) - x86_64-linux, which has real(10) and integer(16) - alpha-linux, which has integer(16)

No regression on any of those. real(16) output does not work on sparc-solaris2.9 since this platform doesn't allow isfinite() to work correctly on long doubles, but this is problem is only partial (huge and very small numbers will be output as +Inf and -Inf insted of their exact value). This could be the case on other platforms, hence a TODO in the patch, describing the problem.

OK for mainline? (and should it be backported to 4.0, too?)

FX

PS: sorry Steve for the first attemp which didn't build on freebsd, I know it's very frustrating to take time to review a patch and to have to do it again... thanks for your help!
2005-06-06  Francois-Xavier Coudert  <coudert@clipper.ens.fr>

	* intrinsics/c99_functions.c (log10l): New log10l function for
	systems where this is not available.
	* c99_protos.h: Prototype for log10l function.
	* libgfortran.h: Use generated kinds.h to define GFC_INTEGER_*,
	GFC_UINTEGER_*, GFC_LOGICAL_*, GFC_REAL_*, GFC_COMPLEX_*. Update
	prototypes for gfc_itoa and xtoa.
	* io/io.h: Update prototypes for set_integer and max_value.
	* io/list_read.c (convert_integer): Use new
	GFC_(INTEGER|REAL)_LARGEST type.
	* io/read.c (set_integer): Likewise.
	(max_value): Likewise.
	(convert_real): Likewise.
	(real_l): Likewise.
	(next_char): Likewise.
	(read_decimal): Likewise.
	(read_radix): Likewise.
	(read_f): Likewise.
	* io/write.c (extract_int): Use new GFC_INTEGER_LARGEST type.
	(extract_real): Use new GFC_REAL_LARGEST type.
	(calculate_exp): Likewise.
	(calculate_G_format): Likewise.
	(output_float): Likewise. Use log10l for long double values.
	Add comment for sprintf format. Use GFC_REAL_LARGEST_FORMAT.
	(write_l): Use new GFC_INTEGER_LARGEST type.
	(write_float): Use new GFC_REAL_LARGEST type.
	(write_int): Remove useless special case for (len < 8).
	(write_decimal): Use GFC_INTEGER_LARGEST.
	(otoa): Use GFC_UINTEGER_LARGEST as argument.
	(btoa): Use GFC_UINTEGER_LARGEST as argument.
	* runtime/error.c (gfc_itoa): Use GFC_INTEGER_LARGEST as
	argument.
	(xtoa): Use GFC_UINTEGER_LARGEST as argument.
	* Makefile.am: Use mk-kinds-h.sh to generate header kinds.h
	with all Fortran kinds available.
	* configure.ac: Check for strtold and log10l.
	* Makefile.in: Regenerate.
	* aclocal.m4: Regenerate.
	* configure: Regenerate.
	* config.h.in: Regenerate.


2005-06-06  Francois-Xavier Coudert  <coudert@clipper.ens.fr>

	* lib/target-supports.exp: Add
	check_effective_target_fortran_large_real and
	check_effective_target_fortran_large_int to check for
	corresponding effective targets.


2005-06-06  Francois-Xavier Coudert  <coudert@clipper.ens.fr>

	* large_integer_kind_1.f90: New test.
	* large_real_kind_1.f90: New test.
Index: gcc/testsuite/lib/target-supports.exp
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/lib/target-supports.exp,v
retrieving revision 1.61
diff -r1.61 target-supports.exp
412a413,488
> # Return 1 if the target supports Fortran real kinds larger than real(8),
> # 0 otherwise.  Cache the result.
> 
> proc check_effective_target_fortran_large_real { } {
>     global et_fortran_large_real_saved
>     global tool
> 
>     if [info exists et_fortran_large_real_saved] {
> 	verbose "check_effective_target_fortran_large_real returning saved $et_fortran_large_real_saved" 2
>     } else {
> 	set et_fortran_large_real_saved 0
> 
> 	# Set up, compile, and execute a test program using large real
> 	# kinds.  Include the current process ID in the file names to
> 	# prevent conflicts with invocations for multiple testsuites.
> 	set src real[pid].f90
>         set exe real[pid].x
> 
> 	set f [open $src "w"]
> 	puts $f "integer,parameter :: k = &"
>         puts $f "  selected_real_kind (precision (0.0_8) + 1)"
>         puts $f "real(kind=k) :: x"
> 	puts $f "end"
> 	close $f
> 
> 	verbose "check_effective_target_fortran_large_real compiling testfile $src" 2
> 	set lines [${tool}_target_compile $src $exe executable ""]
> 	file delete $src
> 
> 	if [string match "" $lines] then {
> 	    # No error message, compilation succeeded.
>   	    set et_fortran_large_real_saved 1
> 	}
>     }
> 
>     return $et_fortran_large_real_saved
> }
> 
> # Return 1 if the target supports Fortran integer kinds larger than
> # integer(8), 0 otherwise.  Cache the result.
> 
> proc check_effective_target_fortran_large_int { } {
>     global et_fortran_large_int_saved
>     global tool
> 
>     if [info exists et_fortran_large_int_saved] {
> 	verbose "check_effective_target_fortran_large_int returning saved $et_fortran_large_int_saved" 2
>     } else {
> 	set et_fortran_large_int_saved 0
> 
> 	# Set up, compile, and execute a test program using large integer
> 	# kinds.  Include the current process ID in the file names to
> 	# prevent conflicts with invocations for multiple testsuites.
> 	set src int[pid].f90
>         set exe int[pid].x
> 
> 	set f [open $src "w"]
> 	puts $f "integer,parameter :: k = &"
>         puts $f "  selected_int_kind (range (0_8) + 1)"
>         puts $f "integer(kind=k) :: i"
> 	puts $f "end"
> 	close $f
> 
> 	verbose "check_effective_target_fortran_large_int compiling testfile $src" 2
> 	set lines [${tool}_target_compile $src $exe executable ""]
> 	file delete $src
> 
> 	if [string match "" $lines] then {
> 	    # No error message, compilation succeeded.
> 	    set et_fortran_large_int_saved 1
> 	}
>     }
> 
>     return $et_fortran_large_int_saved
> }
> 
Index: libgfortran/Makefile.am
===================================================================
RCS file: /cvsroot/gcc/gcc/libgfortran/Makefile.am,v
retrieving revision 1.35
diff -r1.35 Makefile.am
298c298
<     selected_int_kind.inc selected_real_kind.inc
---
>     selected_int_kind.inc selected_real_kind.inc kinds.h
417a418,420
> kinds.h: $(srcdir)/mk-kinds-h.sh
> 	$(SHELL) $(srcdir)/mk-kinds-h.sh '$(FCCOMPILE)' > $@
> 
Index: libgfortran/c99_protos.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libgfortran/c99_protos.h,v
retrieving revision 1.3
diff -r1.3 c99_protos.h
139a140,143
> #ifndef HAVE_LOG10L
> extern long double log10l(long double);
> #endif
> 
Index: libgfortran/configure.ac
===================================================================
RCS file: /cvsroot/gcc/gcc/libgfortran/configure.ac,v
retrieving revision 1.27
diff -r1.27 configure.ac
172c172
< AC_CHECK_FUNCS(getrusage times mkstemp strtof snprintf ftruncate chsize)
---
> AC_CHECK_FUNCS(getrusage times mkstemp strtof strtold snprintf ftruncate chsize)
197a198
> AC_CHECK_LIB([m],[log10l],[AC_DEFINE([HAVE_LOG10L],[1],[libm includes log10l])])
Index: libgfortran/libgfortran.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libgfortran/libgfortran.h,v
retrieving revision 1.24
diff -r1.24 libgfortran.h
200,213c200
< typedef int8_t GFC_INTEGER_1;
< typedef int16_t GFC_INTEGER_2;
< typedef int32_t GFC_INTEGER_4;
< typedef int64_t GFC_INTEGER_8;
< typedef uint8_t GFC_UINTEGER_1;
< typedef uint16_t GFC_UINTEGER_2;
< typedef uint32_t GFC_UINTEGER_4;
< typedef uint64_t GFC_UINTEGER_8;
< typedef GFC_INTEGER_4 GFC_LOGICAL_4;
< typedef GFC_INTEGER_8 GFC_LOGICAL_8;
< typedef float GFC_REAL_4;
< typedef double GFC_REAL_8;
< typedef complex float GFC_COMPLEX_4;
< typedef complex double GFC_COMPLEX_8;
---
> #include "kinds.h"
387c374
< extern char *gfc_itoa (int64_t);
---
> extern char *gfc_itoa (GFC_INTEGER_LARGEST);
390c377
< extern char *xtoa (uint64_t);
---
> extern char *xtoa (GFC_UINTEGER_LARGEST);
Index: libgfortran/intrinsics/c99_functions.c
===================================================================
RCS file: /cvsroot/gcc/gcc/libgfortran/intrinsics/c99_functions.c,v
retrieving revision 1.11
diff -r1.11 c99_functions.c
365a366,409
> 
> #ifndef HAVE_LOG10L
> /* log10 function for long double variables. The version provided here
>    reduces the argument until it fits into a double, then use log10.  */
> long double
> log10l(long double x)
> {
>   long double result;
>   
>   if (x <= 0)
>     return ((long double) log10 ((double) x));
> 
>   result = 0;
>   if (x > 1)
>     {
>       while (x > 1e100L)
>       {
>         result += 100;
>         x /= 1e100L;
>       }
>       while (x > 1e10L)
>       {
>         result += 10;
>         x /= 1e10L;
>       }
>     }
>   else
>     {
>       while (x < 1e-100L)
>       {
>         result -= 100;
>         x *= 1e100L;
>       }
>       while (x < 1e-10L)
>       {
>         result -= 10;
>         x *= 1e10L;
>       }
>     }
> 
>   result += log10 ((double) x);
>   return result;
> }
> #endif
Index: libgfortran/io/io.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libgfortran/io/io.h,v
retrieving revision 1.20
diff -r1.20 io.h
565c565
< extern void set_integer (void *, int64_t, int);
---
> extern void set_integer (void *, GFC_INTEGER_LARGEST, int);
568c568
< extern uint64_t max_value (int, int);
---
> extern GFC_UINTEGER_LARGEST max_value (int, int);
Index: libgfortran/io/list_read.c
===================================================================
RCS file: /cvsroot/gcc/gcc/libgfortran/io/list_read.c,v
retrieving revision 1.22
diff -r1.22 list_read.c
347c347
<   int64_t v, max, max10;
---
>   GFC_INTEGER_LARGEST v, max, max10;
Index: libgfortran/io/read.c
===================================================================
RCS file: /cvsroot/gcc/gcc/libgfortran/io/read.c,v
retrieving revision 1.9
diff -r1.9 read.c
46c46
< set_integer (void *dest, int64_t value, int length)
---
> set_integer (void *dest, GFC_INTEGER_LARGEST value, int length)
49a50,54
> #ifdef HAVE_GFC_INTEGER_16
>     case 16:
>       *((GFC_INTEGER_16 *) dest) = value;
>       break;
> #endif
51c56
<       *((int64_t *) dest) = value;
---
>       *((GFC_INTEGER_8 *) dest) = value;
54c59
<       *((int32_t *) dest) = value;
---
>       *((GFC_INTEGER_4 *) dest) = value;
57c62
<       *((int16_t *) dest) = value;
---
>       *((GFC_INTEGER_2 *) dest) = value;
60c65
<       *((int8_t *) dest) = value;
---
>       *((GFC_INTEGER_1 *) dest) = value;
71c76
< uint64_t
---
> GFC_UINTEGER_LARGEST
74c79,80
<   uint64_t value;
---
>   GFC_UINTEGER_LARGEST value;
>   int n;
77a84,93
> #if defined HAVE_GFC_REAL_16 || defined HAVE_GFC_REAL_10
>     case 16:
>     case 10:
>       value = 1;
>       for (n = 1; n < 4 * length; n++)
>         value = (value << 2) + 3;
>       if (! signed_flag)
>         value = 2*value+1;
>       break;
> #endif
111c127
<       *((float *) dest) =
---
>       *((GFC_REAL_4 *) dest) =
115c131
< 	(float) strtod (buffer, NULL);
---
> 	(GFC_REAL_4) strtod (buffer, NULL);
119c135,144
<       *((double *) dest) = strtod (buffer, NULL);
---
>       *((GFC_REAL_8 *) dest) = strtod (buffer, NULL);
>       break;
> #if defined(HAVE_GFC_REAL_10) && defined (HAVE_STRTOLD)
>     case 10:
>       *((GFC_REAL_10 *) dest) = strtold (buffer, NULL);
>       break;
> #endif
> #if defined(HAVE_GFC_REAL_16) && defined (HAVE_STRTOLD)
>     case 16:
>       *((GFC_REAL_16 *) dest) = strtold (buffer, NULL);
120a146
> #endif
167c193
<       set_integer (dest, 1, length);
---
>       set_integer (dest, (GFC_INTEGER_LARGEST) 1, length);
171c197
<       set_integer (dest, 0, length);
---
>       set_integer (dest, (GFC_INTEGER_LARGEST) 0, length);
266,267c292,294
<   unsigned value, maxv, maxv_10;
<   int v, w, negative;
---
>   GFC_UINTEGER_LARGEST value, maxv, maxv_10;
>   GFC_INTEGER_LARGEST v;
>   int w, negative;
278c305
<       set_integer (dest, 0, length);
---
>       set_integer (dest, (GFC_INTEGER_LARGEST) 0, length);
327c354
<   v = (signed int) value;
---
>   v = value;
353,354c380,382
<   unsigned value, maxv, maxv_r;
<   int v, w, negative;
---
>   GFC_UINTEGER_LARGEST value, maxv, maxv_r;
>   GFC_INTEGER_LARGEST v;
>   int w, negative;
365c393
<       set_integer (dest, 0, length);
---
>       set_integer (dest, (GFC_INTEGER_LARGEST) 0, length);
463c491
<   v = (signed int) value;
---
>   v = value;
511c539
< 	  *((float *) dest) = 0.0f;
---
> 	  *((GFC_REAL_4 *) dest) = 0.0f;
515c543,554
< 	  *((double *) dest) = 0.0;
---
> 	  *((GFC_REAL_8 *) dest) = 0.0;
> 	  break;
> 
> #ifdef HAVE_GFC_REAL_10
> 	case 10:
> 	  *((GFC_REAL_10 *) dest) = 0.0;
> 	  break;
> #endif
> 
> #ifdef HAVE_GFC_REAL_16
> 	case 16:
> 	  *((GFC_REAL_16 *) dest) = 0.0;
516a556
> #endif
Index: libgfortran/io/write.c
===================================================================
RCS file: /cvsroot/gcc/gcc/libgfortran/io/write.c,v
retrieving revision 1.38
diff -r1.38 write.c
40d39
< 
72c71
< static int64_t
---
> static GFC_INTEGER_LARGEST
75c74
<   int64_t i = 0;
---
>   GFC_INTEGER_LARGEST i = 0;
83c82
<       i = *((const int8_t *) p);
---
>       i = *((const GFC_INTEGER_1 *) p);
86c85
<       i = *((const int16_t *) p);
---
>       i = *((const GFC_INTEGER_2 *) p);
89c88
<       i = *((const int32_t *) p);
---
>       i = *((const GFC_INTEGER_4 *) p);
92c91,95
<       i = *((const int64_t *) p);
---
>       i = *((const GFC_INTEGER_8 *) p);
>       break;
> #ifdef HAVE_GFC_INTEGER_16
>     case 16:
>       i = *((const GFC_INTEGER_16 *) p);
93a97
> #endif
101c105
< static double
---
> static GFC_REAL_LARGEST
104c108
<   double i = 0.0;
---
>   GFC_REAL_LARGEST i = 0;
108c112
<       i = *((const float *) p);
---
>       i = *((const GFC_REAL_4 *) p);
111c115,119
<       i = *((const double *) p);
---
>       i = *((const GFC_REAL_8 *) p);
>       break;
> #ifdef HAVE_GFC_REAL_10
>     case 10:
>       i = *((const GFC_REAL_10 *) p);
112a121,126
> #endif
> #ifdef HAVE_GFC_REAL_16
>     case 16:
>       i = *((const GFC_REAL_16 *) p);
>       break;
> #endif
117d130
< 
151c164
< static double
---
> static GFC_REAL_LARGEST
155c168
<   double r = 1.0;
---
>   GFC_REAL_LARGEST r = 1.0;
184c197
< calculate_G_format (fnode *f, double value, int *num_blank)
---
> calculate_G_format (fnode *f, GFC_REAL_LARGEST value, int *num_blank)
190c203
<   double m, exp_d;
---
>   GFC_REAL_LARGEST m, exp_d;
202,203c215
<   if ((m > 0.0 && m < 0.1 - 0.05 / (double) exp_d)
<       || (m >= (double) exp_d - 0.5 ))
---
>   if ((m > 0.0 && m < 0.1 - 0.05 / exp_d) || (m >= exp_d - 0.5 ))
222c234
<       double temp;
---
>       GFC_REAL_LARGEST temp;
274c286
< output_float (fnode *f, double value)
---
> output_float (fnode *f, GFC_REAL_LARGEST value)
324c336,340
<       abslog = fabs(log10 (value));
---
> #if defined(HAVE_GFC_REAL_10) || defined(HAVE_GFC_REAL_16)
>       abslog = fabs((double) log10l(value));
> #else
>       abslog = fabs(log10(value));
> #endif
328c344
<         edigits = 1 + (int) log10 (abslog);
---
>         edigits = 1 + (int) log10(abslog);
349c365,382
<   sprintf (buffer, "%+-#31.*e", ndigits - 1, value);
---
>   /* #   The result will always contain a decimal point, even if no
>    *     digits follow it
>    *
>    * -   The converted value is to be left adjusted on the field boundary
>    *
>    * +   A sign (+ or -) always be placed before a number
>    *
>    * 31  minimum field width
>    *
>    * *   (ndigits-1) is used as the precision
>    *
>    *   e format: [-]d.ddde±dd where there is one digit before the
>    *   decimal-point character and the number of digits after it is
>    *   equal to the precision. The exponent always contains at least two
>    *   digits; if the value is zero, the exponent is 00.
>    */
>   sprintf (buffer, "%+-#31.*" GFC_REAL_LARGEST_FORMAT "e",
>            ndigits - 1, value);
676c709
<   int64_t n;
---
>   GFC_INTEGER_LARGEST n;
692c725
<   double n;
---
>   GFC_REAL_LARGEST n;
701c734,737
<       res = isfinite (n);
---
>       /* TODO: there are some systems where isfinite is not able to work
>                with long double variables. We should detect this case and
> 	       provide our own version for isfinite.  */
>       res = isfinite (n); 
759c795,796
< write_int (fnode *f, const char *source, int len, char *(*conv) (uint64_t))
---
> write_int (fnode *f, const char *source, int len,
>            char *(*conv) (GFC_UINTEGER_LARGEST))
761,762c798
<   uint32_t ns =0;
<   uint64_t n = 0;
---
>   GFC_UINTEGER_LARGEST n = 0;
786,794c822
< 
<   if (len < 8)
<      {
<        ns = n;
<        q = conv (ns);
<      }
<   else
<       q = conv (n);
< 
---
>   q = conv (n);
845c873,874
< write_decimal (fnode *f, const char *source, int len, char *(*conv) (int64_t))
---
> write_decimal (fnode *f, const char *source, int len,
>                char *(*conv) (GFC_INTEGER_LARGEST))
847c876
<   int64_t n = 0;
---
>   GFC_INTEGER_LARGEST n = 0;
933c962
< otoa (uint64_t n)
---
> otoa (GFC_UINTEGER_LARGEST n)
961c990
< btoa (uint64_t n)
---
> btoa (GFC_UINTEGER_LARGEST n)
Index: libgfortran/runtime/error.c
===================================================================
RCS file: /cvsroot/gcc/gcc/libgfortran/runtime/error.c,v
retrieving revision 1.9
diff -r1.9 error.c
72c72
< gfc_itoa (int64_t n)
---
> gfc_itoa (GFC_INTEGER_LARGEST n)
76c76
<   uint64_t t;
---
>   GFC_UINTEGER_LARGEST t;
112c112
< xtoa (uint64_t n)
---
> xtoa (GFC_UINTEGER_LARGEST n)

Attachment: mk-kinds-h.sh
Description: Bourne shell script

! { dg-do run }
! { dg-require-effective-target fortran_large_int }

module testmod
  integer,parameter :: k = selected_int_kind (range (0_8) + 1)
contains
  subroutine testoutput (a,b,length,f)
    integer(kind=k),intent(in) :: a
    integer(kind=8),intent(in) ::  b
    integer,intent(in) :: length
    character(len=*),intent(in) :: f

    character(len=length) :: ca
    character(len=length) :: cb

    write (ca,f) a
    write (cb,f) b
    if (ca /= cb) call abort
  end subroutine testoutput

  subroutine outputstring (a,f,s)
    integer(kind=k),intent(in) :: a
    character(len=*),intent(in) :: f
    character(len=*),intent(in) :: s

    character(len=len(s)) :: c
    
    write (c,f) a
    if (c /= s) call abort
  end subroutine outputstring
end module testmod


! Testing I/O of large integer kinds (larger than kind=8)
program test
  use testmod
  implicit none

  integer(kind=k) :: x
  character(len=20) :: c1, c2

end program test
! { dg-do run }
! { dg-require-effective-target fortran_large_real }

module testmod
  integer,parameter :: k = selected_real_kind (precision (0.0_8) + 1)
contains
  subroutine testoutput (a,b,length,f)
    real(kind=k),intent(in) :: a
    real(kind=8),intent(in) ::  b
    integer,intent(in) :: length
    character(len=*),intent(in) :: f

    character(len=length) :: ca
    character(len=length) :: cb

    write (ca,f) a
    write (cb,f) b
    if (ca /= cb) call abort
  end subroutine testoutput

  subroutine outputstring (a,f,s)
    real(kind=k),intent(in) :: a
    character(len=*),intent(in) :: f
    character(len=*),intent(in) :: s

    character(len=len(s)) :: c
    
    write (c,f) a
    if (c /= s) call abort
  end subroutine outputstring
end module testmod


! Testing I/O of large real kinds (larger than kind=8)
program test
  use testmod
  implicit none

  real(kind=k) :: x
  character(len=20) :: c1, c2

  call testoutput (0.0_k,0.0_8,40,'(F40.35)')

  call testoutput (1.0_k,1.0_8,40,'(F40.35)')
  call testoutput (0.1_k,0.1_8,15,'(F15.10)')
  call testoutput (1e10_k,1e10_8,15,'(F15.10)')
  call testoutput (7.51e100_k,7.51e100_8,15,'(F15.10)')
  call testoutput (1e-10_k,1e-10_8,15,'(F15.10)')
  call testoutput (7.51e-100_k,7.51e-100_8,15,'(F15.10)')

  call testoutput (-1.0_k,-1.0_8,40,'(F40.35)')
  call testoutput (-0.1_k,-0.1_8,15,'(F15.10)')
  call testoutput (-1e10_k,-1e10_8,15,'(F15.10)')
  call testoutput (-7.51e100_k,-7.51e100_8,15,'(F15.10)')
  call testoutput (-1e-10_k,-1e-10_8,15,'(F15.10)')
  call testoutput (-7.51e-100_k,-7.51e-100_8,15,'(F15.10)')

  x = huge(x)
  call outputstring (2*x,'(F20.15)','           +Infinity')
  call outputstring (-2*x,'(F20.15)','           -Infinity')

  write (c1,'(G20.10E5)') x
  write (c2,'(G20.10E5)') -x
  if (c2(1:1) /= '-') call abort
  c2(1:1) = ' '
  if (c1 /= c2) call abort

  x = tiny(x)
  call outputstring (x,'(F20.15)','   0.000000000000000')
  call outputstring (-x,'(F20.15)','   0.000000000000000')

  write (c1,'(G20.10E5)') x
  write (c2,'(G20.10E5)') -x
  if (c2(1:1) /= '-') call abort
  c2(1:1) = ' '
  if (c1 /= c2) call abort
end program test

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]