Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to retrieve the size of a very big file ?

32 views
Skip to first unread message

Jean-Baptiste Faure

unread,
Nov 19, 2010, 5:10:09 AM11/19/10
to
Hi,

I need to retrieve the size of a file in order to evaluate the amount of
data it contains.
Up to know I used the gnu extension stat(). The problem is that stat()
returns an array of type integer. Unfortunately my file is about 6,5 Go
> 2^31-1 bytes

So is there an alternative to stat() which return integer*8 values ?

Best regards
JBF
--
Seuls des formats ouverts peuvent assurer la pérennité de vos documents

robin

unread,
Nov 19, 2010, 7:22:17 AM11/19/10
to
"Jean-Baptiste Faure" <jean-bapt...@cemagref.fr> wrote in message news:ic5ie2$ahu$1...@news.albasani.net...

| Hi,
|
| I need to retrieve the size of a file in order to evaluate the amount of
| data it contains.
| Up to know I used the gnu extension stat(). The problem is that stat()
| returns an array of type integer. Unfortunately my file is about 6,5 Go
| > 2^31-1 bytes
|
| So is there an alternative to stat() which return integer*8 values ?

You'd first need a Fortran compiler that implements 64-bit integers.


Jean-Baptiste Faure

unread,
Nov 19, 2010, 7:45:54 AM11/19/10
to
You mean integers single precision coded on 64 bits ?
My system is a Linux 32 bits and I use gcc/gfortran. I want use a
compiler which is free software.

Arjen Markus

unread,
Nov 19, 2010, 8:08:01 AM11/19/10
to
On 19 nov, 13:45, Jean-Baptiste Faure <jean-
baptiste.fa...@cemagref.fr> wrote:
> Le 19/11/2010 13:22, robin a écrit :> "Jean-Baptiste Faure"<jean-baptiste.fa...@cemagref.fr>  wrote in messagenews:ic5ie2$ahu$1...@news.albasani.net...

> > | Hi,
> > |
> > | I need to retrieve the size of a file in order to evaluate the amount of
> > | data it contains.
> > | Up to know I used the gnu extension stat(). The problem is that stat()
> > | returns an array of type integer. Unfortunately my file is about 6,5 Go
> > |>  2^31-1 bytes
> > |
> > | So is there an alternative to stat() which return integer*8 values ?
>
> > You'd first need a Fortran compiler that implements 64-bit integers.
>
> You mean integers single precision coded on 64 bits ?
> My system is a Linux 32 bits and I use gcc/gfortran. I want use a
> compiler which is free software.
>
> JBF
>
> --
> Seuls des formats ouverts peuvent assurer la pérennité de vos documents

This little program:

! chk64bits.f90 --
! Does this compiler allow for 64 bits integers?
!
program chk64bits

integer :: k

k = selected_int_kind( 10 )

if ( k > 0 ) then
write(*,*) 'Large integers have type: ', k
else
write(*,*) 'Large integers NOT supported'
endif
end program chk64bits

answered "8" on Linux with gfortran 4.1.2 (yes, pretty old)

Regards,

Arjen

Jean-Baptiste Faure

unread,
Nov 19, 2010, 9:45:35 AM11/19/10
to

Ok, my gfortran answered "8" too.
But stat() returns integer*4 values :
http://gcc.gnu.org/onlinedocs/gfortran/STAT.html#STAT
and the size returned by stat() for my big file is negative :-)

So I am looking for an alternative. This alternative must be portable on
MS-Windows.
At the moment I am using a python script launched by system() subroutine.
No problem on Linux where, I guess, python is always installed, but on
MS-Windows I am not sure. So it is not a perfect solution.

Regards

Daniel Carrera

unread,
Nov 19, 2010, 11:43:50 AM11/19/10
to
On Nov 19, 1:45 pm, Jean-Baptiste Faure <jean-
baptiste.fa...@cemagref.fr> wrote:
> Le 19/11/2010 13:22, robin a écrit :> "Jean-Baptiste Faure"<jean-baptiste.fa...@cemagref.fr>  wrote

> > You'd first need a Fortran compiler that implements 64-bit integers.
>
> You mean integers single precision coded on 64 bits ?
> My system is a Linux 32 bits and I use gcc/gfortran. I want use a
> compiler which is free software.

I hope gfortran supports 64 bit integers, but if it doesn't, that
would explain a problem I've been having with gfortran recently. If I
declare a variable as "integer (kind=8)" I still cannot assign to it a
value bigger than (2^31 - 1).

Daniel.

JB

unread,
Nov 19, 2010, 12:04:28 PM11/19/10
to
On 2010-11-19, Daniel Carrera <dcar...@gmail.com> wrote:
> I hope gfortran supports 64 bit integers, but if it doesn't, that
> would explain a problem I've been having with gfortran recently. If I
> declare a variable as "integer (kind=8)" I still cannot assign to it a
> value bigger than (2^31 - 1).

Presumably the problem is rather that the literal which you're
assigning to the variable is of default kind.

(And yes, gfortran does support 64-bit integers, provided that the
target does)

--
JB

JB

unread,
Nov 19, 2010, 12:09:39 PM11/19/10
to
On 2010-11-19, Jean-Baptiste Faure <jean-bapt...@cemagref.fr> wrote:
> Hi,
>
> I need to retrieve the size of a file in order to evaluate the amount of
> data it contains.
> Up to know I used the gnu extension stat(). The problem is that stat()
> returns an array of type integer. Unfortunately my file is about 6,5 Go
> > 2^31-1 bytes
>
> So is there an alternative to stat() which return integer*8 values ?

You could try opening the file as unformatted stream with
position="append", then use inquire(pos=) to get the file position.
This gives you the size in units of "file storage units", which in the
case of gfortran is 1 byte.


--
JB

Tobias Burnus

unread,
Nov 19, 2010, 12:19:42 PM11/19/10
to
Regarding the optaining of the file size: Unfortunately, gfortran's
(l,f)stat() vendor intrinsics currently only support 4-byte integers.

However, something like the following should work:

integer :: unit
integer(8) :: pos
open(newunit=unit, file="test.dat", access="stream", &
position="append", status="old")
inquire(unit, pos=pos)
close(unit)
print *, pos-1
end


On 11/19/2010 05:43 PM, Daniel Carrera wrote:
> I hope gfortran supports 64 bit integersbut if it doesn't, that


> would explain a problem I've been having with gfortran recently. If I
> declare a variable as "integer (kind=8)" I still cannot assign to it a
> value bigger than (2^31 - 1).

Do you assign an 4-byte or 8-byte integer? Assigning a > 2**32 8-byte
integer should work. Talking about supported integer types, gfortran
also supports a 16-byte integer on some of the platforms. Example:


$ cat test.f90

use iso_fortran_env, only: integer_kinds
implicit none
integer(8) :: i
print '(a,*(i0:", "))', 'kinds: ', integer_kinds
print *, huge(1_1)
print *, huge(1_2)
print *, huge(1_4)
print *, huge(1_8)
print *, huge(1_16)
i = (2_8)**40
print *, i
end

$ gfortran test.f90 && ./a.out

kinds: 1, 2, 4, 8, 16
127
32767
2147483647
9223372036854775807
170141183460469231731687303715884105727
1099511627776

Tobias

PS: Sorry for being in F2008 mood and using at least three F2008 features.

Richard Maine

unread,
Nov 19, 2010, 1:52:38 PM11/19/10
to
JB <f...@bar.invalid> wrote:

If one assumes f2003 support such as unformatted stream, one might as
well also try the f2003 standard version of exactly the functionality
requested. I suppose it ought to be equivalent in most cases, but I'd
try the simpler version first.

Namely, look at the size= specifier in the inquire statement, which
retrieves "the size of the file in file storage units."

It is certainly possible that a compiler would support f2003's stream,
yet not also support the related f2003 size=. Insert my usual bitch
about having to make long lists individual f2003 features instead of
just summarizing it as "an f2003 compiler." This case also illustrates
one of the reasons I bitch about that as doing feature lists means one
has to debate exactly what bits count as part of what itemized feature.
Does size= count as part of stream I/O or not?

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain

JB

unread,
Nov 19, 2010, 1:57:50 PM11/19/10
to
On 2010-11-19, Richard Maine <nos...@see.signature> wrote:
> JB <f...@bar.invalid> wrote:
>
>> On 2010-11-19, Jean-Baptiste Faure <jean-bapt...@cemagref.fr> wrote:
>> > Hi,
>> >
>> > I need to retrieve the size of a file in order to evaluate the amount of
>> > data it contains.
>> > Up to know I used the gnu extension stat(). The problem is that stat()
>> > returns an array of type integer. Unfortunately my file is about 6,5 Go
>> > > 2^31-1 bytes
>> >
>> > So is there an alternative to stat() which return integer*8 values ?
>>
>> You could try opening the file as unformatted stream with
>> position="append", then use inquire(pos=) to get the file position.
>> This gives you the size in units of "file storage units", which in the
>> case of gfortran is 1 byte.
>
> If one assumes f2003 support such as unformatted stream, one might as
> well also try the f2003 standard version of exactly the functionality
> requested. I suppose it ought to be equivalent in most cases, but I'd
> try the simpler version first.
>
> Namely, look at the size= specifier in the inquire statement, which
> retrieves "the size of the file in file storage units."

Ah, you're right. I forgot about this feature of inquire. And yes,
size= works as of gfortran 4.4.

--
JB

Richard Maine

unread,
Nov 19, 2010, 2:01:58 PM11/19/10
to
JB <f...@bar.invalid> wrote:

> On 2010-11-19, Daniel Carrera <dcar...@gmail.com> wrote:
> > I hope gfortran supports 64 bit integers, but if it doesn't, that
> > would explain a problem I've been having with gfortran recently. If I
> > declare a variable as "integer (kind=8)" I still cannot assign to it a
> > value bigger than (2^31 - 1).
>
> Presumably the problem is rather that the literal which you're
> assigning to the variable is of default kind.

I'd say that presumption has very high odds. I'd just like to
reemphasize it because the basics are so important. It comes up more
often in reals than integers, but the findamental principle is the same
and is a very important one.

Literal constants have kinds, just like variables. When you write 1.234
in Fortran source code, it does no mean just the value 1.234. It means
an approximation of that value in a default real representation.
Likewise when you write 12345678901234 (thought oughtta be enough
digits), it does not mean just that value. It means that value
represented as a default integer. At least you don't have the
approximation business for integers, but you still have the
representation issue. If default integer doesn't have a representation
for that value, your code is invalid. Compilers might or might not
helpfully notice that error.

If you want to use a non-default kind, you should write something like
12345678901234_thekind, where thekind is preferebly a suitable named
constant. (Don't hardwire 8 or you will come to regret it; the value 8,
while common, is not guaranteed by the standard and is not used by all
compilers).

glen herrmannsfeldt

unread,
Nov 19, 2010, 3:10:26 PM11/19/10
to
Jean-Baptiste Faure <jean-bapt...@cemagref.fr> wrote:

> I need to retrieve the size of a file in order to evaluate the
> amount of data it contains.
> Up to know I used the gnu extension stat(). The problem is that stat()
> returns an array of type integer. Unfortunately my file is about 6,5 Go
> > 2^31-1 bytes

> So is there an alternative to stat() which return integer*8 values ?

stat() is a unix system call that, for many years, returned the
size as a 32 bit integer when disks were much smaller than 4GB.

As disks and then files exceeded 4GB, it took some time to
catch up. In the mean time, some implemented a stat64() call
(C callable, not necessarily with a Fortran interface).

As far as I know, most have now gone to a stat structure
(it is a C struct, defined in stat.h) with a 64 bit integer
for the length, but it is hard to say what is portable.

It might even be that in your array of 32 bit integers the
high 32 bits are in a different word.

Your system might have stat64(), or a 64 bit version of the
C callable stat that you could use through C interoperability,
though you would have to generate the appropriate structure yourself.

You could also call DIR with system(). (Windows specific.)

-- glen

Daniel Carrera

unread,
Nov 19, 2010, 4:22:10 PM11/19/10
to
On Nov 19, 6:19 pm, Tobias Burnus <bur...@net-b.de> wrote:
> On 11/19/2010 05:43 PM, Daniel Carrera wrote:
> > I hope gfortran supports 64 bit integersbut if it doesn't, that
> > would explain a problem I've been having with gfortran recently. If I
> > declare a variable as "integer (kind=8)" I still cannot assign to it a
> > value bigger than (2^31 - 1).
>
> Do you assign an 4-byte or 8-byte integer?

This is the relevant code:

integer (kind=8) :: bigint

bigint = 2147483647 ! OK
bigint = 2147483648 ! FAILS


The first value is (2^31 - 1). The compile error is: "Integer too big
for its kind". But then I saw your sample code:

> print *, huge(1_1)
> print *, huge(1_2)
> print *, huge(1_4)
> print *, huge(1_8)
> print *, huge(1_16)


When I add "_8" to the number, I can use numbers all the way up to
"2^63 - 1":


! WORKS!!
bigint = 9223372036854775807_8


I wasn't familiar with the "_8" thingie. Clearly it is specifying that
the number is an 8 byte int, but I don't understand why the compiler
can't figure that it by itself. Btw, my version of gfortran doesn't
support "_16". Maybe my version is too old?


Daniel.

Daniel Carrera

unread,
Nov 19, 2010, 4:49:41 PM11/19/10
to
On Nov 19, 8:01 pm, nos...@see.signature (Richard Maine) wrote:
> If you want to use a non-default kind, you should write something like
> 12345678901234_thekind, where thekind is preferebly a suitable named
> constant. (Don't hardwire 8 or you will come to regret it; the value 8,
> while common, is not guaranteed by the standard and is not used by all
> compilers).

Interesting. I didn't know about the "_foo" feature until today, much
less that you could use a variable instead of hard-coding "_8", but it
works!

integer, parameter :: big = 8
integer (kind=big) :: bigint

bigint = 9223372036854775807_big

print *,bigint
print *,huge(1_big)

Cheers,
Daniel.

Tobias Burnus

unread,
Nov 19, 2010, 4:54:21 PM11/19/10
to
Daniel Carrera wrote:
>> Do you assign an 4-byte or 8-byte integer?
> bigint = 2147483647 ! OK
> bigint = 2147483648 ! FAILS
>
>
> The first value is (2^31 - 1). The compile error is: "Integer too big
> for its kind".
>
> When I add "_8" to the number, I can use numbers all the way up to
> "2^63 - 1":

Regarding the kind number ("8"): The proper way is to define it
somewhere as, e.g.

integer, parameter :: big_int = selected_int_kind(10)
! for numbers between -10**R < number < 10**R
integer(big_int) :: myInt
myInt = 9223372036854775807_big_int

The reason is that the available kind numbers and their meaning are
compiler dependent. I think kind=4 and kind=8 are quite common for
4-byte and 8-byte integers, but that's far from universal. (For
instance, the NAG compiler uses different numbers.) At least, the
standard guarantees that there is a 64 bit integer available (more
precisely: one with 18 decimal digits).


> I wasn't familiar with the "_8" thingie. Clearly it is specifying that
> the number is an 8 byte int, but I don't understand why the compiler
> can't figure that it by itself.

Well, how should the compiler know what you want? Let's assume do

call mySub(10)

should it now assume that 10 is a kind=1 integer because it fits into a
single byte?

Fortran always made the distinction between different kinds. For
instance for REAL: There is a big difference between 0.1e0 and 0.1d0 --
which can also be written as 0.1_<kind> where <kind> is typically some
constant (PARAMETER) one has defined somewhere, but one can (but
shouldn't) also directly use the numeric value.

Note: For floating point numbers knowing the concept of real kinds for
literals is even more important as one can easily loose precision (cf.
Richard Main's post). For instance in
real(kind(0.0d0) :: double_prec
double_prec = sqrt(2.)*0.1
one does all the calculation in single precision; as long as the number
is exactly representable (such as 1.0 and 0.0 for binary radix) that's
fine. But e.g. 0.1 and sqrt(2.0) are different from 0.1d0 and sqrt(2.0d0).

By the way, that's not different to, e.g., C where one also has 0.1f,
0.1 and 0.1L or 1 and 1L.


> Btw, my version of gfortran doesn't
> support "_16". Maybe my version is too old?

Well, I think that's rather due to the hardware. I think on a 32-bit x86
(i686, Intel/AMD CPU) a 128-bit integer does not exist (in GCC) while
for instance on the 64bit x86-64 (AMD64, Intel64) it does exist.

Tobias

steve

unread,
Nov 19, 2010, 4:54:53 PM11/19/10
to

The right hand side of an expression is evaluated without any
knowledge
of the LHS. Thus, in an expression of the form 'I = 42', the value 42
has
default integer kind irrespective of the kind type parameter for I.
If I is
not of default integer kind, then upon assignment 42 is converted to
the
kind type of I.

The '_8' thingie is the Standard method for expressing the kind of
a literal constant. Again note, '8' is nonportable and one should
use selected_int_kind to get the correct value.

--
steve

glen herrmannsfeldt

unread,
Nov 19, 2010, 4:56:07 PM11/19/10
to
Daniel Carrera <dcar...@gmail.com> wrote:
(snip)

> Interesting. I didn't know about the "_foo" feature until today, much
> less that you could use a variable instead of hard-coding "_8", but it
> works!

A parameter, not a variable.


> integer, parameter :: big = 8
> integer (kind=big) :: bigint

> bigint = 9223372036854775807_big

> print *,bigint
> print *,huge(1_big)

-- glen

Daniel Carrera

unread,
Nov 19, 2010, 5:47:50 PM11/19/10
to
On Nov 19, 10:54 pm, Tobias Burnus <bur...@net-b.de> wrote:

> Daniel Carrera wrote:
> Regarding the kind number ("8"): The proper way is to define it
> somewhere as, e.g.
>
> integer, parameter :: big_int = selected_int_kind(10)
> ! for numbers between -10**R < number < 10**R
> integer(big_int) :: myInt
> myInt = 9223372036854775807_big_int

Thanks. I'm surprised that this isn't standardized. I'll bet that this
is something people do all the time. You mentioned in your email how
Fortran uses "1.0E0" and "1.0D0". I wish they had done something like
that for integers.

Question: Is there any difference between "integer(big_int)" and
"integer (kind=big_int)"? Is one more common / recommended?


> The reason is that the available kind numbers and their meaning are
> compiler dependent. I think kind=4 and kind=8 are quite common for
> 4-byte and 8-byte integers, but that's far from universal. (For
> instance, the NAG compiler uses different numbers.) At least, the
> standard guarantees that there is a 64 bit integer available (more
> precisely: one with 18 decimal digits).

Interesting. You'd think this is something they'd standardize.


> Well, how should the compiler know what you want? Let's assume do
>
>    call mySub(10)
>
> should it now assume that 10 is a kind=1 integer because it fits into a
> single byte?

If mySub() is declared to have a parameter of type 'foo' then the
compiler should interpret 10 to be "10_foo" because nothing else would
make sense.

> Note: For floating point numbers knowing the concept of real kinds for
> literals is even more important as one can easily loose precision (cf.
> Richard Main's post). For instance in
> real(kind(0.0d0) :: double_prec
>    double_prec = sqrt(2.)*0.1
> one does all the calculation in single precision; as long as the number
> is exactly representable (such as 1.0 and 0.0 for binary radix) that's
> fine. But e.g. 0.1 and sqrt(2.0) are different from 0.1d0 and sqrt(2.0d0).

OOoops! Thanks for the warning. I would never have caught that.


> By the way, that's not different to, e.g., C where one also has 0.1f,
> 0.1 and 0.1L or 1 and 1L.

Ok. But I'm not a big expert on C. I learnt it at school years ago,
but never really used it.


> > Btw, my version of gfortran doesn't
> > support "_16". Maybe my version is too old?
>
> Well, I think that's rather due to the hardware. I think on a 32-bit x86
> (i686, Intel/AMD CPU) a 128-bit integer does not exist (in GCC) while
> for instance on the 64bit x86-64 (AMD64, Intel64) it does exist.

Ok. Thanks.

Cheers,
Daniel.

steve

unread,
Nov 19, 2010, 6:31:08 PM11/19/10
to
On Nov 19, 2:47 pm, Daniel Carrera <dcarr...@gmail.com> wrote:
> On Nov 19, 10:54 pm, Tobias Burnus <bur...@net-b.de> wrote:
>
> > Daniel Carrera wrote:
> > Regarding the kind number ("8"): The proper way is to define it
> > somewhere as, e.g.
>
> > integer, parameter :: big_int = selected_int_kind(10)
> > ! for numbers between -10**R < number < 10**R
> > integer(big_int) :: myInt
> > myInt = 9223372036854775807_big_int
>
> Thanks. I'm surprised that this isn't standardized.

To what does "this" refer? The use of a suffix to indicate
the kind is in the standard. The exact values of what the
suffixes are not given in the standard.

I


> Question: Is there any difference between "integer(big_int)" and
> "integer (kind=big_int)"? Is one more common / recommended?

No and no/no.


> > Well, how should the compiler know what you want? Let's assume do
>
> >    call mySub(10)
>
> > should it now assume that 10 is a kind=1 integer because it fits into a
> > single byte?
>
> If mySub() is declared to have a parameter of type 'foo' then the
> compiler should interpret 10 to be "10_foo" because nothing else would
> make sense.

'a parameter' should be 'a dummy argument'.

function t
real t
call mysub(10)
t = 1.
end function t

gfortran -c t.f90

So, where is gfortran (or any compiler) getting the information
concerning mysub's interface?

> > Note: For floating point numbers knowing the concept of real kinds for
> > literals is even more important as one can easily loose precision (cf.
> > Richard Main's post). For instance in
> > real(kind(0.0d0) :: double_prec
> >    double_prec = sqrt(2.)*0.1
> > one does all the calculation in single precision; as long as the number
> > is exactly representable (such as 1.0 and 0.0 for binary radix) that's
> > fine. But e.g. 0.1 and sqrt(2.0) are different from 0.1d0 and sqrt(2.0d0).
>
> OOoops! Thanks for the warning. I would never have caught that.

That's what compiler warning options are for. Use -Wall -Wextra with
gfortran.

--
steve

glen herrmannsfeldt

unread,
Nov 19, 2010, 6:32:47 PM11/19/10
to
Daniel Carrera <dcar...@gmail.com> wrote:
> On Nov 19, 10:54 pm, Tobias Burnus <bur...@net-b.de> wrote:
>> Daniel Carrera wrote:
>> Regarding the kind number ("8"): The proper way is to define it
>> somewhere as, e.g.

>> integer, parameter :: big_int = selected_int_kind(10)
>> ! for numbers between -10**R < number < 10**R
>> integer(big_int) :: myInt
>> myInt = 9223372036854775807_big_int

> Thanks. I'm surprised that this isn't standardized. I'll bet that this
> is something people do all the time. You mentioned in your email how
> Fortran uses "1.0E0" and "1.0D0". I wish they had done something like
> that for integers.

It is standardized, just as it is written above.



> Question: Is there any difference between "integer(big_int)" and
> "integer (kind=big_int)"? Is one more common / recommended?

One might be more readable to some people.

(snip)


>> Well, how should the compiler know what you want? Let's assume do

>>    call mySub(10)

>> should it now assume that 10 is a kind=1 integer because
>> it fits into a single byte?

> If mySub() is declared to have a parameter of type 'foo' then the
> compiler should interpret 10 to be "10_foo" because nothing else would
> make sense.

Traditionally, you didn't declare the types of arguments, so the
only way was to get it right. For constants, it could be done, but
for variables, where you want the returned value, it doesn't make
so much sense.

C will do it if a prototype is in scope, but it is more obvious
for call by value, where it doesn't have to convert back on return.

PL/I does it, as there are too many different types. Instead of
KIND, PL/I declares variables with the desired precision.

DCL I FIXED BINARY(31); /* 32 bit signed integer */

DLC J FIXED BINARY(30); (Most likely also a 32 bit integer.)

Constants have the type that they are written in, such that 10
is FIXED DECIMAL(2), and 999 is FIXED DECIMAL(3). If needed,
and the type of the arguments is declared, the value will be
converted, but it is then treated as an expression with a temporary,
and any changes are not brought back.

I wouldn't mind seeing some of that added to Fortran, though.

(snip)

> OOoops! Thanks for the warning. I would never have caught that.

>> By the way, that's not different to, e.g., C where one also has 0.1f,
>> 0.1 and 0.1L or 1 and 1L.

> Ok. But I'm not a big expert on C. I learnt it at school years ago,
> but never really used it.

Well, it is slightly different in C. Floating point constants
are (double), unless you add the trailing f for (float).
Single precision intrinsics were only added in C99. Previously,
they were all done as (double), and converted back.



>> > Btw, my version of gfortran doesn't
>> > support "_16". Maybe my version is too old?

>> Well, I think that's rather due to the hardware. I think on a 32-bit x86
>> (i686, Intel/AMD CPU) a 128-bit integer does not exist (in GCC) while
>> for instance on the 64bit x86-64 (AMD64, Intel64) it does exist.

It isn't that much harder to do in IA32, though.

-- glen

Richard Maine

unread,
Nov 19, 2010, 7:24:03 PM11/19/10
to
Daniel Carrera <dcar...@gmail.com> wrote:

> On Nov 19, 10:54 pm, Tobias Burnus <bur...@net-b.de> wrote:
> > Daniel Carrera wrote:
> > Regarding the kind number ("8"): The proper way is to define it
> > somewhere as, e.g.

...


> Thanks. I'm surprised that this isn't standardized.

I'm also confused by the referent of "this". All the mentioned stuff is
standardized except for the specific kind value 8, which Tobias and
others were recommending against using. The selected_int_kind intrinsic
provides a standardized way to get the appropriate kind value. I don't
think I'll go into the discussion of why the standard doesn't specify
specific kind values except to mention that my preference would have
been exactly the opposite - I don't even think they should have been
numeric. If they weren't numeric, the question of what number to use
would not come up.

> Fortran uses "1.0E0" and "1.0D0". I wish they had done something like
> that for integers.

Note, however, that this is exactly the opposite of the general
direction of the language evolution. The 1.0D0 notation is an older
style that many people (such as myself, though you could probably guess
that) consider deprecated. It does not integrate particularly well with
the kind system and with things like extended precisions. I don't
recommend using it in new code except possibly as a handy way to get the
kind number for double precision from kind(0.0d0).



> Question: Is there any difference between "integer(big_int)" and
> "integer (kind=big_int)"? Is one more common / recommended?

As others mentioned, no to both questions. My own personal style - and I
should emphasize that this is just mine; I haven't seen it widely
adopted - is to use a parameter name that has _kind in it for clarity,
but then to omit the kind= from the syntax. For example, I have a kind
parameter named (the derivation of the name ought to be clear enough)
i8_kind, which I use in syntax like integer(i8_kind). Because kind
parameters are used so much, I do like to keep them from being too
long-winded, particularly as my _kind already is alittle verbose. That's
why I have just i8_kind instead of something longer such as
big_int_kind.

Again, I'm just explaining my personal style choices. I'm not suggesting
there is anything particularly superior about them.

> > The reason is that the available kind numbers and their meaning are
> > compiler dependent.
>

> Interesting. You'd think this is something they'd standardize.

As noted above, that's a topic I think I'll avoid for now.

> > Well, how should the compiler know what you want? Let's assume do
> >
> > call mySub(10)
> >
> > should it now assume that 10 is a kind=1 integer because it fits into a
> > single byte?
>
> If mySub() is declared to have a parameter of type 'foo' then the
> compiler should interpret 10 to be "10_foo" because nothing else would
> make sense.

And how would the compiler necessarily know about the dummy argument
(not parameter, as Steve noted)? Oh, you would have a system that was
different depending on whether the procedure interface was explicit or
not? I don't think you'd find that very popular. Or you would eliminate
implicit interface procedures? I don't much like implicit interface
procedures, but one has to work in the real world where throwing out the
existing language and starting over isn't an option.

Or, even with explicit interfaces, how about generics where there might
be specifics for multiple different kinds? That is quite typical of
generics, that being what they most commonly are for. If you are going
to select which specific to use based on the kind of the actual
argument, but select the kind of the actual argument based on which
specific gets used, you have a problem. Either that or you are going to
have to invent some kind of prioritization rule that people will need to
memorize.

And that's just one particular case out of a large number of the places
where the compiler would need to select an appropriate kind for a
literal. For another, consider

write(lun) 12345

That's an unformatted write. Yes, the kind matters if you expect other
code to be able to correctly read the file. There is no way for the
compiler to guess what one you might want, though. I suppose one could
say that this is a case where the user has to specify it right.

Go down this path and you are going to end up with a complicated set of
cases and rules. Compilers will probably be able to get them right, but
good luck in getting users to. More likely is that users would get used
to the compiler guessing the intended kind in some cases, and they would
get blindsided when it didn't happen in others.

The current rules do force a bit of verbosity when using non-default
kinds, but they are at least simple and consistent. If you want a
non-default kind, you specify it. Always. Hard to get simpler than that
since "let the compiler guess the right kind" isn't going to work
consistently.

There are compilers that try to guess what the user meant instead of
what the user actually said for the kind in some contexts. I strongly
recommend against counting on such features (and I wish that the
compilers generated warnings for them by default - the "by default"
being a critical point of that wish).

Oh. As an aside, Tobias said

>> At least, the
>> standard guarantees that there is a 64 bit integer available (more
>> precisely: one with 18 decimal digits).

I believe that might be the case for f2008, but it is not so for
anything earlier.

James Van Buskirk

unread,
Nov 19, 2010, 7:55:49 PM11/19/10
to
"Richard Maine" <nos...@see.signature> wrote in message
news:1js7nxd.oa807n18ohi8mN%nos...@see.signature...

> Daniel Carrera <dcar...@gmail.com> wrote:

>> Fortran uses "1.0E0" and "1.0D0". I wish they had done something like
>> that for integers.

> Note, however, that this is exactly the opposite of the general
> direction of the language evolution. The 1.0D0 notation is an older
> style that many people (such as myself, though you could probably guess
> that) consider deprecated. It does not integrate particularly well with
> the kind system and with things like extended precisions. I don't
> recommend using it in new code except possibly as a handy way to get the
> kind number for double precision from kind(0.0d0).

And 1.0E0 and 1.0D0 don't mix well with generic programming. With
1.0_wp you get a different version of the code by just starting off
with a different (valid) value for wp.

>> Question: Is there any difference between "integer(big_int)" and
>> "integer (kind=big_int)"? Is one more common / recommended?

> As others mentioned, no to both questions. My own personal style - and I
> should emphasize that this is just mine; I haven't seen it widely
> adopted - is to use a parameter name that has _kind in it for clarity,
> but then to omit the kind= from the syntax. For example, I have a kind
> parameter named (the derivation of the name ought to be clear enough)
> i8_kind, which I use in syntax like integer(i8_kind). Because kind
> parameters are used so much, I do like to keep them from being too
> long-winded, particularly as my _kind already is alittle verbose. That's
> why I have just i8_kind instead of something longer such as
> big_int_kind.

A word of caution: there is a difference between:

character(kind=C_CHAR)

and:

character(C_CHAR)

For character type declarations remember that LEN is positioned
before KIND. This is part of gfortran PR 46496.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


glen herrmannsfeldt

unread,
Nov 20, 2010, 2:33:54 AM11/20/10
to
Richard Maine <nos...@see.signature> wrote:
> Daniel Carrera <dcar...@gmail.com> wrote:
(snip)

>> Thanks. I'm surprised that this isn't standardized.



> I'm also confused by the referent of "this". All the mentioned stuff is
> standardized except for the specific kind value 8, which Tobias and
> others were recommending against using. The selected_int_kind intrinsic
> provides a standardized way to get the appropriate kind value. I don't
> think I'll go into the discussion of why the standard doesn't specify
> specific kind values except to mention that my preference would have
> been exactly the opposite - I don't even think they should have been
> numeric. If they weren't numeric, the question of what number to use
> would not come up.

OK, but what do you think about the PL/I method. Not that it
would have been possible to graft into Fortran, but just for
comparison purposes. In PL/I, all declarations specify the
desired precision, and, for fixed point the scale factor
(position of the radix point). Some of the popular declarations
are FLOAT DECIMAL(15), or FLOAT BINARY(23) for floating point,
and FIXED BINARY(31,0) for fixed point.

The nice thing is that you always specify exactly what you need.
Except that you rarely know exactly what you need, so most of
the time you find values related to what you expect the processor
to have available. You can specify the precision needed in
either decimal digits (like SELECTED_xxx_KIND), or bits.
Until recently, hardware supported one base for floating point,
and the appropriate precision was used in that base, from the
specified number of decimal digits or bits. As some processors
support fixed point in both decimal (BCD) and binary, it is usual,
but not required, that the base match that specified. If a scale
factor (position of the radix point) other than zero is specified,
that can result in multiplies and divides by powers of ten to
align the decimal point.

PL/I constants have the base, scale, and precision that they
are written in, but conversions are done when needed, and one
normally expects the compiler to do constant conversion at
compile time. (When I was first learning PL/I, it was still
recommended that Fortran users write floating point constants
to avoid run time conversion. That probably isn't true now, though.)
The constant 1.23 has attributes FIXED DECIMAL(3,2), and will
be converted, as necessary, possibly to FLOAT BIN(53).

>> Fortran uses "1.0E0" and "1.0D0". I wish they had done
>> something like that for integers.

> Note, however, that this is exactly the opposite of the general
> direction of the language evolution. The 1.0D0 notation is an older
> style that many people (such as myself, though you could probably guess
> that) consider deprecated. It does not integrate particularly well with
> the kind system and with things like extended precisions.

Some IBM compilers use a Q for extended precision, 1.Q0,
and have intrinsic like QSQRT and QSIN.

> I don't recommend using it in new code except possibly as a handy
> way to get the kind number for double precision from kind(0.0d0).

(snip)

>> > call mySub(10)

>> > should it now assume that 10 is a kind=1 integer because it fits into a
>> > single byte?

>> If mySub() is declared to have a parameter of type 'foo' then the
>> compiler should interpret 10 to be "10_foo" because nothing else would
>> make sense.

> And how would the compiler necessarily know about the dummy argument
> (not parameter, as Steve noted)? Oh, you would have a system that was
> different depending on whether the procedure interface was explicit or
> not?

That is what C and PL/I do. The Java rules are more complicated,
especially with more than one parameter. (Recently my daughter
started learning Java. She gets confused when I say argument,
and mean parameter.) Java will promote to a wider type, if
needed, without much complaint.

> I don't think you'd find that very popular. Or you would eliminate
> implicit interface procedures? I don't much like implicit interface
> procedures, but one has to work in the real world where throwing out
> the existing language and starting over isn't an option.

Convert when the interface is available, and not convert when
it isn't, doesn't seem so bad. At least for constants and expressions,
where no result will be returned.



> Or, even with explicit interfaces, how about generics where there might
> be specifics for multiple different kinds? That is quite typical of
> generics, that being what they most commonly are for. If you are going
> to select which specific to use based on the kind of the actual
> argument, but select the kind of the actual argument based on which
> specific gets used, you have a problem. Either that or you are going to
> have to invent some kind of prioritization rule that people will need to
> memorize.

That is pretty much what Java does. Multiple methods with the
same name but different types are resolved using such rules.
I haven't tried to memorize them, though.



> And that's just one particular case out of a large number of the places
> where the compiler would need to select an appropriate kind for a
> literal. For another, consider

> write(lun) 12345

> That's an unformatted write. Yes, the kind matters if you expect other
> code to be able to correctly read the file. There is no way for the
> compiler to guess what one you might want, though. I suppose one could
> say that this is a case where the user has to specify it right.

Well, there are always the conversion intrinsics, and they might
be needed for variables or expressions, too.



> Go down this path and you are going to end up with a complicated set of
> cases and rules. Compilers will probably be able to get them right, but
> good luck in getting users to. More likely is that users would get used
> to the compiler guessing the intended kind in some cases, and they would
> get blindsided when it didn't happen in others.

The Java rules, for both assignment and method calls, require
a cast for narrowing conversions, but not for widening. In most
cases, that will give the correct result, though possibly with
more computation. A byte or short will convert to int if needed,
int to float or double, long to double. So if you Math.sqrt(123)
the integer will convert to float (or maybe double).



> The current rules do force a bit of verbosity when using non-default
> kinds, but they are at least simple and consistent. If you want a
> non-default kind, you specify it. Always. Hard to get simpler than that
> since "let the compiler guess the right kind" isn't going to work
> consistently.

(snip)

-- glen

Richard Maine

unread,
Nov 20, 2010, 4:56:44 AM11/20/10
to
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

> Richard Maine <nos...@see.signature> wrote:

> > I don't even think they [kinds] should have been


> > numeric. If they weren't numeric, the question of what number to use
> > would not come up.
>
> OK, but what do you think about the PL/I method. Not that it
> would have been possible to graft into Fortran, but just for
> comparison purposes. In PL/I, all declarations specify the
> desired precision, and, for fixed point the scale factor
> (position of the radix point). Some of the popular declarations
> are FLOAT DECIMAL(15), or FLOAT BINARY(23) for floating point,
> and FIXED BINARY(31,0) for fixed point.

I don't like it at all. For a start it is verbose. I far prefer putting
the verbosity in a parameter. That's particularly so when the verbose
bits do not obvioously relate to my requirements. As you noted yourself,
those "magic numbers" relate more to the representations of particular
systems rather than to what users directly think of as requirements. I
used to do some PL/I and I distinctly recall those "magic numbers" as
meaning very little to me other than that 15 was how I asked for double
precision. If one ever did port to a mchine where 15 wasn't a good
number, you;d have to fix it up all over the code.

But I'm not interested in starting a debate about it. You asked what I
thought about it as a direct question. I answered. That's all I have to
say on the question. If someone else likes it, that's fine with me.

> Some IBM compilers use a Q for extended precision, 1.Q0,
> and have intrinsic like QSQRT and QSIN.

Yes, I know. But that's a hack. As noted in regards to D, it doesn't
generalize. What happens of someone has another precision someday? You
have to invent a new letter for each precision, and it is part of the
language syntax, which means, among other things, that you haveto be
careful about some letters having conflicts. Kinds generalize to any
number of precisions without requiring any new language syntax per kind.

> > Either that or you are going to
> > have to invent some kind of prioritization rule that people will need to
> > memorize.
>
> That is pretty much what Java does. Multiple methods with the
> same name but different types are resolved using such rules.
> I haven't tried to memorize them, though.

Fun. :-( I'm a far bigger fan of having one very trivial rule for
everything instead of something that people have to memorize. Enough
people complain about the simple rule; I hate to imagine trying to tell
them to deal with a set of rules complicated enough that I hadn't even
managed to memorize.

> > I suppose one could
> > say that this is a case where the user has to specify it right.
>
> Well, there are always the conversion intrinsics,

That seems an irrelevant syntax detail. That would just amount to a
particular syntax for how to "specify it right."

Tobias Burnus

unread,
Nov 20, 2010, 6:41:37 AM11/20/10
to
Richard Maine wrote:
>> Some IBM compilers use a Q for extended precision, 1.Q0,
>> and have intrinsic like QSQRT and QSIN.
>
> Yes, I know. But that's a hack. As noted in regards to D, it doesn't
> generalize. What happens of someone has another precision someday?

Well, you do not have to wait that long. gfortran of GCC 4.6 has on
x86-64/ia64 4-byte, 8-byte, 10-byte (80 bit) and (new) 16-byte (128 bit)
floating point numbers; the 4, 8, and 10 are in hardware; the 16 byte
one does more in software and is thus slower.

(For completeness, the 'q' is not supported in gfortran, neither as
prefix to intrinsics nor as edit descriptor nor in floating point literals.)

> have to invent a new letter for each precision, and it is part of the
> language syntax, which means, among other things, that you haveto be
> careful about some letters having conflicts. Kinds generalize to any
> number of precisions without requiring any new language syntax per kind.

It will get even more complicated, if one adds decimal floating points,
which might happen (to gfortran) at some point. The Fortran (2008)
standard allows via the RADIX argument of selected_real_kind intrinsic
for (e.g.) decimal floating points.


>> Well, there are always the conversion intrinsics,

Explicit conversion also works in Fortran via INT, REAL, ...

Tobias

robin

unread,
Nov 20, 2010, 10:29:27 AM11/20/10
to
"glen herrmannsfeldt" <g...@ugcs.caltech.edu> wrote in message news:ic7tl1$m9o$1...@news.eternal-september.org...

| Richard Maine <nos...@see.signature> wrote:
| > Daniel Carrera <dcar...@gmail.com> wrote:
| (snip)
|
| >> Thanks. I'm surprised that this isn't standardized.
|
| > I'm also confused by the referent of "this". All the mentioned stuff is
| > standardized except for the specific kind value 8, which Tobias and
| > others were recommending against using. The selected_int_kind intrinsic
| > provides a standardized way to get the appropriate kind value. I don't
| > think I'll go into the discussion of why the standard doesn't specify
| > specific kind values except to mention that my preference would have
| > been exactly the opposite - I don't even think they should have been
| > numeric. If they weren't numeric, the question of what number to use
| > would not come up.
|
| OK, but what do you think about the PL/I method. Not that it
| would have been possible to graft into Fortran, but just for
| comparison purposes. In PL/I, all declarations specify the
| desired precision, and, for fixed point the scale factor
| (position of the radix point).

They don't have to.
For ordinary work, the keywords are sufficient,
e.g., FLOAT and FIXED BINARY
without the numbers, in which case the default precisions are used.

| Some of the popular declarations
| are FLOAT DECIMAL(15), or FLOAT BINARY(23) for floating point,
| and FIXED BINARY(31,0) for fixed point.

FLOAT (15) is sufficient for FLOAT DECIMAL (15).

| The nice thing is that you always specify exactly what you need.

You mean, you *can* specify a precision if you wish.

| Except that you rarely know exactly what you need,

I would say that in most cases you know exactly what you need.

| so most of
| the time you find values related to what you expect the processor
| to have available.

That isn't the case for most of the declarations one uses.
The sizes of binary FLOATS and binary INTEGERS
has been fairly "standardised" for the past 30 years at
64/32 bits respectively.
For decimal fixed-point work, any precision up to the maximum
will be found in programs.

| You can specify the precision needed in
| either decimal digits (like SELECTED_xxx_KIND), or bits.
| Until recently, hardware supported one base for floating point,
| and the appropriate precision was used in that base, from the
| specified number of decimal digits or bits. As some processors
| support fixed point in both decimal (BCD) and binary, it is usual,
| but not required, that the base match that specified. If a scale
| factor (position of the radix point) other than zero is specified,
| that can result in multiplies and divides by powers of ten to
| align the decimal point.

Actual multiplication or division via a hardware multiplier/divider
is not required for decimal fixed-point. Such are implemented
with a simple shift.

| PL/I constants have the base, scale, and precision that they
| are written in, but conversions are done when needed, and one
| normally expects the compiler to do constant conversion at
| compile time. (When I was first learning PL/I, it was still
| recommended that Fortran users write floating point constants
| to avoid run time conversion. That probably isn't true now, though.)
| The constant 1.23 has attributes FIXED DECIMAL(3,2), and will
| be converted, as necessary, possibly to FLOAT BIN(53).

Constants that are intended to be floating-point
are usually written with an exponent.


robin

unread,
Nov 20, 2010, 10:30:02 AM11/20/10
to
"Richard Maine" <nos...@see.signature> wrote in message news:1js8euo.lu0s2y1rzpa8N%nos...@see.signature...

| glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
|
| > OK, but what do you think about the PL/I method. Not that it
| > would have been possible to graft into Fortran, but just for
| > comparison purposes. In PL/I, all declarations specify the
| > desired precision, and, for fixed point the scale factor
| > (position of the radix point). Some of the popular declarations
| > are FLOAT DECIMAL(15), or FLOAT BINARY(23) for floating point,
| > and FIXED BINARY(31,0) for fixed point.
|
| I don't like it at all. For a start it is verbose. I far prefer putting
| the verbosity in a parameter.

You can do that in PL/I also.
BTW, it isn't as "verbose" as it looks.
FLOAT DECIMAL (15) can be written as FLOAT (15).
As well, DECIMAL can be abbreviated to DEC and BINARY to BIN.

| That's particularly so when the verbose
| bits do not obvioously relate to my requirements. As you noted yourself,
| those "magic numbers" relate more to the representations of particular
| systems rather than to what users directly think of as requirements.

Typically, for floating-point, the precision would be specified as
number of decimal digits. But only if the default precision
(like REAL :: in Fortran) were not sufficient.

| I used to do some PL/I and I distinctly recall those "magic numbers" as
| meaning very little to me other than that 15 was how I asked for double
| precision. If one ever did port to a mchine where 15 wasn't a good
| number, you;d have to fix it up all over the code.

No you don't (or didn't).
Just as in Fortran, a particular precision can be specified once.


robin

unread,
Nov 21, 2010, 3:02:14 AM11/21/10
to
"John W Kennedy" <jwk...@attglobal.net> wrote in message news:4ce876ea$0$20170$607e...@cv.net...
| But not with the same breakdown of exponent and fraction, or the IEEE
| implicit high-order 1.

True, but the same 32/64 combination is the dominant form.

| > For decimal fixed-point work, any precision up to the maximum
| > will be found in programs.
| >
| > | You can specify the precision needed in
| > | either decimal digits (like SELECTED_xxx_KIND), or bits.
| > | Until recently, hardware supported one base for floating point,
| > | and the appropriate precision was used in that base, from the
| > | specified number of decimal digits or bits. As some processors
| > | support fixed point in both decimal (BCD) and binary, it is usual,
| > | but not required, that the base match that specified. If a scale
| > | factor (position of the radix point) other than zero is specified,
| > | that can result in multiplies and divides by powers of ten to
| > | align the decimal point.
| >
| > Actual multiplication or division via a hardware multiplier/divider
| > is not required for decimal fixed-point. Such are implemented
| > with a simple shift.
|

| Not if the hardware does not include the stated base.

Even if the hardware doesn't support decimal
[decimal BCD is still dominant in hardware, besides binary]
and the arithmetic is implemented in fixed binary,
multiplication and division by powers of 10 is still a shift.


Daniel Carrera

unread,
Nov 21, 2010, 6:38:21 AM11/21/10
to
On Nov 20, 12:31 am, steve <kar...@comcast.net> wrote:
> > > integer(big_int) :: myInt
> > > myInt = 9223372036854775807_big_int
>
> > Thanks. I'm surprised that this isn't standardized.
>
> To what does "this" refer?  The use of a suffix to indicate
> the kind is in the standard.  The exact values of what the
> suffixes are not given in the standard.

By "this" I meant that I'm surprised that the standard doesn't specify
a prefix that always means "8 byte int" or "4 byte int", etc. So
instead you have thousands of programmers writing custom modules to
give portable names to types. So I write "_bigint" in my code, and you
write "_int8" and someone else writes "_i64" and we all mean the same
thing.

> > If mySub() is declared to have a parameter of type 'foo' then the
> > compiler should interpret 10 to be "10_foo" because nothing else would
> > make sense.
>
> 'a parameter' should be 'a dummy argument'.
>
> function t
>    real t
>    call mysub(10)
>    t = 1.
> end function  t
>
> gfortran -c t.f90
>
> So, where is gfortran (or any compiler) getting the information
> concerning mysub's interface?

I'm surprised that you can compile that without knowing anything about
mysub(). Interesting.


> > OOoops! Thanks for the warning. I would never have caught that.
>
> That's what compiler warning options are for.  Use -Wall -Wextra with
> gfortran.

I always use -Wall. I wasn't aware of -Wextra. Scanning through the
documentation, it seems to be mainly for C/C++, but I'll start using
it anyway.

Cheers,
Daniel.

Daniel Carrera

unread,
Nov 21, 2010, 7:22:08 AM11/21/10
to
On Nov 20, 1:24 am, nos...@see.signature (Richard Maine) wrote:

> Daniel Carrera <dcarr...@gmail.com> wrote:
> > Thanks. I'm surprised that this isn't standardized.
>
> I'm also confused by the referent of "this". All the mentioned stuff is
> standardized except for the specific kind value 8, which Tobias and
> others were recommending against using. The selected_int_kind intrinsic
> provides a standardized way to get the appropriate kind value. I don't
> think I'll go into the discussion of why the standard doesn't specify
> specific kind values except to mention that my preference would have
> been exactly the opposite - I don't even think they should have been
> numeric. If they weren't numeric, the question of what number to use
> would not come up.

I see that I was ambiguous. What I meant is that I'm surprised that
the standard doesn't specify a common suffix like "_bigint", "_int8"
or "_i64", or "_8bytes" instead of having all the programmers come up
with their own libraries with their own prefix.


> > Fortran uses "1.0E0" and "1.0D0". I wish they had done something like
> > that for integers.
>
> Note, however, that this is exactly the opposite of the general
> direction of the language evolution. The 1.0D0 notation is an older
> style that many people (such as myself, though you could probably guess
> that) consider deprecated. It does not integrate particularly well with
> the kind system and with things like extended precisions. I don't
> recommend using it in new code except possibly as a handy way to get the
> kind number for double precision from kind(0.0d0).


Possibly dumb question: What is extended precision?

What do you recommend for new code? I see that there is a
"SELECTED_REAL_KIND" function, so you could write:

integer, parameter :: real32 = selected_real_kind(6)
integer, parameter :: real64 = selected_real_kind(8)

print *,1.0_real32
print *,1.0_real64

That seems to work well. Is this what you do? I'm new at Fortran, and
I have no legacy code to maintain, so I might as well form the right
habits from the start.


> > > Well, how should the compiler know what you want? Let's assume do
>
> > >    call mySub(10)
>
> > > should it now assume that 10 is a kind=1 integer because it fits into a
> > > single byte?
>
> > If mySub() is declared to have a parameter of type 'foo' then the
> > compiler should interpret 10 to be "10_foo" because nothing else would
> > make sense.
>
> And how would the compiler necessarily know about the dummy argument

> (not parameter, as Steve noted)?... Or you would eliminate


> implicit interface procedures? I don't much like implicit interface
> procedures, but one has to work in the real world where throwing out the
> existing language and starting over isn't an option.


This is where my noobiness clearly shows... I don't know what a dummy
argument is, or what an implicit interface procedure is... Then again,
that's why I ask questions here :)


> Or, even with explicit interfaces, how about generics where there might
> be specifics for multiple different kinds? That is quite typical of
> generics, that being what they most commonly are for.

Oh, I think I've seen those. You define a function several times, with
different input kinds, and then make an "interface", so the program
decides which function to call based on the input. So, for example, I
could write a quicksort function that could sort ints, floats or
doubles. Is that what a "generic" is?

Yeah, I can see how generics can only work if it is the programmer's
job to explicitly say what type each value is like "10_int8", etc.

> The current rules do force a bit of verbosity when using non-default
> kinds, but they are at least simple and consistent. If you want a
> non-default kind, you specify it. Always. Hard to get simpler than that
> since "let the compiler guess the right kind" isn't going to work
> consistently.

Yeah. I'm starting to see that now. Like with generics and printing.

Thanks for the help. I'm learning :-)

Cheers,
Daniel.

dpb

unread,
Nov 21, 2010, 9:57:17 AM11/21/10
to
Daniel Carrera wrote:
...

> By "this" I meant that I'm surprised that the standard doesn't specify
> a prefix that always means "8 byte int" or "4 byte int", etc. So
> instead you have thousands of programmers writing custom modules to
> give portable names to types. So I write "_bigint" in my code, and you
> write "_int8" and someone else writes "_i64" and we all mean the same
> thing.

And, assuming no mistake made by any of the three, all will be able to
take the code written and compile it on any compliant compiler and it
will mean the same thing there or, in the case of a compiler that
doesn't support the particular KIND (and that is the actual data type,
not KIND number), that will also be known. So, the Standard will have
done what it's intended; provide portability at the source code level.
That the Standard is vendor-neutral and silent on most implementation
details is a very conscious decision and there would be far less chance
of there being a Standard if that were not so...

...

>> function t
>> real t
>> call mysub(10)
>> t = 1.
>> end function t
>>
>> gfortran -c t.f90
>>
>> So, where is gfortran (or any compiler) getting the information
>> concerning mysub's interface?
>
> I'm surprised that you can compile that without knowing anything about
> mysub(). Interesting.

...

You _DO_ know something (actually for the simple case shown, everything
required) about mysub. Or, more precisely, it's the programmer's
responsibility to not lie to the compiler so the compiler will presume
that you haven't and therefore it "knows" what it needs to know.

Recall (or be aware) that Fortran treats each program unit (program,
function or subroutine) as a totally independent entity--even if the
file containing the code for MYSUB above were to be submitted to the
compiler at the same time as the above function calling it, there is no
communication between the two for there to be any additional information
available when compiling function T as when the two are compiled totally
independently.

With F90+ and the use of modules and/or internal procedures the compiler
can and will generate explicit instead of only implicit interfaces such
that the information is shared.

--

Dan Nagle

unread,
Nov 21, 2010, 11:32:54 AM11/21/10
to
Hello,

On 2010-11-21 09:57:17 -0500, dpb said:
> So, the Standard will have done what it's intended; provide
> portability at the source code level. That the Standard is
> vendor-neutral and silent on most implementation details is a very
> conscious decision and there would be far less chance of there being a
> Standard if that were not so...

The f08 standard has added named constants for integers
and reals. This was suggested by vendors in response
to their customers for greater portability. See 13.8.2.11
and 13.8.2.21 in the f08 standard for details.

Notice the use of named constants, rather than literal constants.

Personally, I try to use a module I write for type kind values.
I must admit I sometimes skip the step, especially for smaller,
throw-away programs.

--
Cheers!

Dan Nagle

nm...@cam.ac.uk

unread,
Nov 21, 2010, 11:48:21 AM11/21/10
to
In article <icbhjl$mum$1...@news.eternal-september.org>,

Dan Nagle <dann...@verizon.net> wrote:
>On 2010-11-21 09:57:17 -0500, dpb said:
>> So, the Standard will have done what it's intended; provide
>> portability at the source code level. That the Standard is
>> vendor-neutral and silent on most implementation details is a very
>> conscious decision and there would be far less chance of there being a
>> Standard if that were not so...
>
>The f08 standard has added named constants for integers
>and reals. This was suggested by vendors in response
>to their customers for greater portability. See 13.8.2.11
>and 13.8.2.21 in the f08 standard for details.

Though, regrettably, such actions actually REDUCE portability, as
those of us with long memories can witness :-(

Fortran has always had the convention that standard INTEGER is
a suitable size for array indexing, which means that we can, did
and do write code that will work equally well on machines with
16, 24, 32, 36, 48, 60 or 64 bit addressing. Bind bit sizes in,
and that's gone.


Regards,
Nick Maclaren.

Gary L. Scott

unread,
Nov 21, 2010, 11:56:19 AM11/21/10
to

99.9% of everything I write must include bit manipulation of some sort
so I always need to specify or know the size of an integer in bits.
>
>
> Regards,
> Nick Maclaren.

nm...@cam.ac.uk

unread,
Nov 21, 2010, 12:09:13 PM11/21/10
to
In article <HqmdnfUwPdCt0nTR...@supernews.com>,

Gary L. Scott <garyl...@sbcglobal.net> wrote:
>>>
>>> The f08 standard has added named constants for integers
>>> and reals. This was suggested by vendors in response
>>> to their customers for greater portability. See 13.8.2.11
>>> and 13.8.2.21 in the f08 standard for details.
>>
>> Though, regrettably, such actions actually REDUCE portability, as
>> those of us with long memories can witness :-(
>>
>> Fortran has always had the convention that standard INTEGER is
>> a suitable size for array indexing, which means that we can, did
>> and do write code that will work equally well on machines with
>> 16, 24, 32, 36, 48, 60 or 64 bit addressing. Bind bit sizes in,
>> and that's gone.
>
>99.9% of everything I write must include bit manipulation of some sort
>so I always need to specify or know the size of an integer in bits.

What's the problem? There's a perfectly good BIT_SIZE intrinsic.
Write genuinely portable code, and it will work for all reasonable
results returned from that.


Regards,
Nick Maclaren.

James Van Buskirk

unread,
Nov 21, 2010, 12:57:09 PM11/21/10
to
<nm...@cam.ac.uk> wrote in message news:icbigl$tad$1...@gosset.csi.cam.ac.uk...

> In article <icbhjl$mum$1...@news.eternal-september.org>,
> Dan Nagle <dann...@verizon.net> wrote:

>>The f08 standard has added named constants for integers
>>and reals. This was suggested by vendors in response
>>to their customers for greater portability. See 13.8.2.11
>>and 13.8.2.21 in the f08 standard for details.

13.8.2.11 is a little nicer than C_INT8_T, C_INT16_T, C_INT32_T,
C_INT64_T from ISO_C_BINDING, but it also doesn't have a 128-bit
integer KIND. 13.8.2.21 doesn't have a fourth REAL KIND. Let's
see if gfortran has it yet:

C:\gfortran\clf\kinds>type kinds.f90
program kinds
implicit none
integer, parameter :: sp = kind(1.0)
integer, parameter :: dp = kind(1.0d0)
integer, parameter :: ep_preferred = &
selected_real_kind(precision(0.0_dp)+1)
integer, parameter :: ep = (1+sign(1,ep_preferred))/2*ep_preferred+ &
(1-sign(1,ep_preferred))/2*dp
integer, parameter :: qp_preferred = &
selected_real_kind(precision(0.0_ep)+1)
integer, parameter :: qp = (1+sign(1,qp_preferred))/2*qp_preferred+ &
(1-sign(1,qp_preferred))/2*ep
integer, parameter :: ik1 = selected_int_kind(2)
integer, parameter :: ik2 = selected_int_kind(4)
integer, parameter :: ik4 = selected_int_kind(9)
integer, parameter :: ik8_preferred = selected_int_kind(18)
integer, parameter :: ik8 = (1+sign(1,ik8_preferred))/2*ik8_preferred+ &
(1-sign(1,ik8_preferred))/2*ik4
integer, parameter :: ik16_preferred = selected_int_kind(38)
integer, parameter :: ik16 = (1+sign(1,ik16_preferred))/2*ik16_preferred+
&
(1-sign(1,ik16_preferred))/2*ik8

write(*,10) 'sp = ', sp, ', precision(sp) = ', precision(1.0_sp)
write(*,10) 'dp = ', dp, ', precision(dp) = ', precision(1.0_dp)
write(*,10) 'ep = ', ep, ', precision(ep) = ', precision(1.0_ep)
write(*,10) 'qp = ', qp, ', precision(qp) = ', precision(1.0_qp)
write(*,10) 'ik1 = ', ik1, ', range(ik1) = ', range(1_ik1)
write(*,10) 'ik2 = ', ik2, ', range(ik2) = ', range(1_ik2)
write(*,10) 'ik4 = ', ik4, ', range(ik4) = ', range(1_ik4)
write(*,10) 'ik8 = ', ik8, ', range(ik8) = ', range(1_ik8)
write(*,10) 'ik16 = ', ik16, ', range(ik16) = ', range(1_ik16)
write(*,20) 'Testing LOGICAL(.TRUE.,ik1) = ', LOGICAL(.TRUE.,ik1)
write(*,20) 'Testing LOGICAL(.TRUE.,ik2) = ', LOGICAL(.TRUE.,ik2)
write(*,20) 'Testing LOGICAL(.TRUE.,ik4) = ', LOGICAL(.TRUE.,ik4)
write(*,20) 'Testing LOGICAL(.TRUE.,ik8) = ', LOGICAL(.TRUE.,ik8)
write(*,20) 'Testing LOGICAL(.TRUE.,ik16) = ', LOGICAL(.TRUE.,ik16)
10 format(3(a,i0))
20 format(a,L1)
end program kinds

C:\gfortran\clf\kinds>gfortran kinds.f90 -okinds

C:\gfortran\clf\kinds>kinds
sp = 4, precision(sp) = 6
dp = 8, precision(dp) = 15
ep = 10, precision(ep) = 18
qp = 10, precision(qp) = 18
ik1 = 1, range(ik1) = 2
ik2 = 2, range(ik2) = 4
ik4 = 4, range(ik4) = 9
ik8 = 8, range(ik8) = 18
ik16 = 16, range(ik16) = 38
Testing LOGICAL(.TRUE.,ik1) = T
Testing LOGICAL(.TRUE.,ik2) = T
Testing LOGICAL(.TRUE.,ik4) = T
Testing LOGICAL(.TRUE.,ik8) = T
Testing LOGICAL(.TRUE.,ik16) = T

C:\gfortran\clf\kinds>gfortran -v
Built by Equation Solution <http://www.Equation.com>.
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=c:/gcc_equation/bin/../libexec/gcc/x86_64-w64-mingw32/4.6.0/
lto-wrapper.exe
Target: x86_64-w64-mingw32
Thread model: win32
gcc version 4.6.0 20101113 (experimental) (GCC)

So REAL(KIND=16) is not there in last week's snapshot, although
INTEGER(KIND=16) is.

> Though, regrettably, such actions actually REDUCE portability, as
> those of us with long memories can witness :-(

> Fortran has always had the convention that standard INTEGER is
> a suitable size for array indexing, which means that we can, did
> and do write code that will work equally well on machines with
> 16, 24, 32, 36, 48, 60 or 64 bit addressing. Bind bit sizes in,
> and that's gone.

I thought that the convention was that standard INTEGER had the same
size as standard REAL, N1830.pdf, section 16.5.3.2. With the
exponential growth of memory over the years, standard INTEGER is
drifting away from being suitable for indexing, requiring optional
KIND arguments to many inquiry intrinsics. Even the C language's
treatment of single precision REALs as second-class citizens hasn't
caused a quantum leap up to 64-bit reals as default in Fortran.

BTW, when gfortran breaks binary compatibility in a big way with
new array descriptors, is it also going to switch to 64-bit hidden
CHARACTER LENs on 64-bit platforms like ifort?

Richard Maine

unread,
Nov 21, 2010, 1:03:35 PM11/21/10
to
Daniel Carrera <dcar...@gmail.com> wrote:

> I see that I was ambiguous. What I meant is that I'm surprised that
> the standard doesn't specify a common suffix like "_bigint", "_int8"
> or "_i64", or "_8bytes" instead of having all the programmers come up
> with their own libraries with their own prefix.

Ah. I see. Well then that isn't too far off from a position of mine as
well. There is a need for programmers to be able to specify their own
for some purposes, but I also think that the standard should provide a
few of the more common ones as a simplification. I made a proposal along
that line which didn't make it into f2003, but I believe something like
it is in f2008.

> Possibly dumb question: What is extended precision?

Not dumb at all. I didn't realize you didn't know, but there's no
particular reason why you necessarily would have. That's a common term
for a precision higher than double. I suppose I could have said quad
precision, which some compilers have, but I intentionally used a more
general term to avoid implying that there was only one more possible
precision. I ended up needing to make that point more eplicit anyway in
reply to Glenn.

>
> What do you recommend for new code? I see that there is a
> "SELECTED_REAL_KIND" function, so you could write:
>
> integer, parameter :: real32 = selected_real_kind(6)
> integer, parameter :: real64 = selected_real_kind(8)
>
> print *,1.0_real32
> print *,1.0_real64
>
> That seems to work well. Is this what you do? I'm new at Fortran, and
> I have no legacy code to maintain, so I might as well form the right
> habits from the start.

Yes, that is much like what I, and many others here, do. (The only
differences are in details that don't matter.) Then put the definitions
of your real32 and real64 in a module and USE that module wherever
needed. Probably the most important part is to define parameters for the
purpose. As long as you do that, the exact definitions are then easy to
go back and change if a need to do so comes up. Using selected_real_kind
will probably keep you from needing to change them anyway unless your
problem changes.

> This is where my noobiness clearly shows... I don't know what a dummy
> argument is, or what an implicit interface procedure is... Then again,
> that's why I ask questions here :)

Oh. Then I've wandered way to far into esoteria for my audience. I
probably should have stopped with some generality like that things can
get much more complicated and that the simple rule of specifying the
kind explicitly avoids many of those complications. We probably don't
want to take this particilar thread through the entire language
investigating what things might be like if it were different. I usually
try to avoid saying things along the line of "it is more complicated
than you can appreciate at the moment" because they sound too haughty;
plus statements like that aren't as helpful as they could be. I prefer
to give at least a hint of what some of the complications are. But here,
I don't want that to lead down the path of recapping half of the
language.

In *VERY* short, a dummy argument is the thing that you declare in the
argument list of a subroutine or function, as in

subroutine my_sub(this_is_a_dummy_argument)

Then the "actual argumemnt" is what you put in the reference to the
subroutine or function as in

call my_sub(this_is_an_actual_argument)

During execution of the subroutine, the dummy argument is "associated
with" the actual argument. Exactly what the association implies can vary
widely and would not be a short discussion at all. It sort of means that
they are linked in such a way that changes to one cause changes to the
other. It is a lot like the dummy being a pointer to the actual.

Implicit interfaces. Um. That's where the compiler has no information
about what the subroutine expects when it is compiling the call, so it
just has to infer what the subroutine must need from what the call looks
like. That's how (almost) all procedures were prior to f90.

> > Or, even with explicit interfaces, how about generics where there might
> > be specifics for multiple different kinds? That is quite typical of
> > generics, that being what they most commonly are for.
>
> Oh, I think I've seen those. You define a function several times, with
> different input kinds, and then make an "interface", so the program
> decides which function to call based on the input. So, for example, I
> could write a quicksort function that could sort ints, floats or
> doubles. Is that what a "generic" is?

Yes. Just like all of the intrinsics. For example sqrt can take the sqrt
of either a single or double precision real (or other precisions of the
compiler has such). There might be different procedures for those two
precisions behind the scenes, but the compiler decides which one to use
based on precision of the actual argument in the reference.

Richard Maine

unread,
Nov 21, 2010, 1:23:36 PM11/21/10
to
Dan Nagle <dann...@verizon.net> wrote:

> The f08 standard has added named constants for integers
> and reals. This was suggested by vendors in response
> to their customers for greater portability.

Not just vendors. I'm quite sure I recall writing a proposal for that. I
almost said "the proposal" instead of "a proposal", but it is possible
that there was another parallel one.

And my main aim was not portability. We already had reasonably good
portability in the area with the selected_*_kind intrinsics. There we
some quite minor picky areas in theory, but they weren't a significant
problem in practice.

In my view, the main reason for such a thing is simplicity. New users
need to learn about using kinds very early - early enough that you don't
want to force them into understanding the verbosity of
selected_real_kind. That's particularly so because up through f2003
selected_real_kind requires you to specify precision in decimal digits.
I think f2008 adds an option, which is nice, but also makes for more
things to explain to a new user.

It is *SO* much easier to tell a new user that _real64 (of whatever the
name) is the kind for a 64-bit real than to explain

integer, parameter :: my_kind = selected_real_kind(12)

What's this "magic number" 12, for example? Yes, I know that in some
theoretical world, a user ought to know the precisions requirements of
his code and be able to say "I need 12 decimal digits." But the world I
inhabit is full of people who know that they need 64-bit reals and find
that 12 to be mysterious.

James Van Buskirk

unread,
Nov 21, 2010, 1:51:45 PM11/21/10
to
"Richard Maine" <nos...@see.signature> wrote in message
news:1jsavdi.cmup008qmoh0N%nos...@see.signature...

> Daniel Carrera <dcar...@gmail.com> wrote:


>> Oh, I think I've seen those. You define a function several times, with
>> different input kinds, and then make an "interface", so the program
>> decides which function to call based on the input. So, for example, I
>> could write a quicksort function that could sort ints, floats or
>> doubles. Is that what a "generic" is?

> Yes. Just like all of the intrinsics. For example sqrt can take the sqrt
> of either a single or double precision real (or other precisions of the
> compiler has such). There might be different procedures for those two
> precisions behind the scenes, but the compiler decides which one to use
> based on precision of the actual argument in the reference.

I have an example with heapsort that could be easily converted to
quicksort:

http://groups.google.com/group/comp.lang.fortran/msg/7dd8df7d0aaa14a3?hl=en

glen herrmannsfeldt

unread,
Nov 21, 2010, 3:56:42 PM11/21/10
to
Richard Maine <nos...@see.signature> wrote:
> Daniel Carrera <dcar...@gmail.com> wrote:

(snip)
>> Possibly dumb question: What is extended precision?

> Not dumb at all. I didn't realize you didn't know, but there's no
> particular reason why you necessarily would have. That's a common term
> for a precision higher than double. I suppose I could have said quad
> precision, which some compilers have, but I intentionally used a more
> general term to avoid implying that there was only one more possible
> precision. I ended up needing to make that point more eplicit anyway in
> reply to Glenn.

IBM, for the 360/85 and S/370 calls the 128 bit format extended
precision, but then again the 32 and 64 bit are called short and
long precision. (The assembler nmemonic use E, D, and X.)

I believe the 80 bit "temporary real" format for the Intel x87
is also called extended precision, especially as quad isn't an
appropriate term for that one.

-- glen

steve

unread,
Nov 21, 2010, 4:51:28 PM11/21/10
to
On Nov 21, 9:57 am, "James Van Buskirk" <not_va...@comcast.net> wrote:

> So REAL(KIND=16) is not there in last week's snapshot, although
> INTEGER(KIND=16) is.

Your code does what you asked the compiler to do, but
it may not be what one might expect on i386-*-freebsd.

laptop:kargl[203] ./z


sp = 4, precision(sp) = 6
dp = 8, precision(dp) = 15

ep = 16, precision(ep) = 33
qp = 16, precision(qp) = 33


ik1 = 1, range(ik1) = 2
ik2 = 2, range(ik2) = 4
ik4 = 4, range(ik4) = 9
ik8 = 8, range(ik8) = 18

ik16 = 8, range(ik16) = 18


Testing LOGICAL(.TRUE.,ik1) = T
Testing LOGICAL(.TRUE.,ik2) = T
Testing LOGICAL(.TRUE.,ik4) = T
Testing LOGICAL(.TRUE.,ik8) = T
Testing LOGICAL(.TRUE.,ik16) = T

laptop:kargl[208] cat k.f90
program kinds
integer, parameter :: &
& sp = selected_real_kind(r = 30), &
& dp = selected_real_kind(r = 300), &
& ep = selected_real_kind(r = 3000), &
& qp = selected_real_kind(r = 3000, p = precision(1.d0) + 1)
print '(4(I0,1X))', sp, dp, ep, qp
end program kinds
laptop:kargl[208] gfc4x -o z k.f90
laptop:kargl[209] ./z
4 8 10 16

--
steve

Jean-Baptiste Faure

unread,
Nov 22, 2010, 4:14:37 AM11/22/10
to
Le 19/11/2010 19:57, JB a ᅵcrit :
> On 2010-11-19, Richard Maine<nos...@see.signature> wrote:
>> JB<f...@bar.invalid> wrote:
>>
>>> On 2010-11-19, Jean-Baptiste Faure<jean-bapt...@cemagref.fr> wrote:
>>>> Hi,
>>>>
>>>> I need to retrieve the size of a file in order to evaluate the amount of
>>>> data it contains.
>>>> Up to know I used the gnu extension stat(). The problem is that stat()
>>>> returns an array of type integer. Unfortunately my file is about 6,5 Go
>>>>> 2^31-1 bytes
>>>>
>>>> So is there an alternative to stat() which return integer*8 values ?
>>>
>>> You could try opening the file as unformatted stream with
>>> position="append", then use inquire(pos=) to get the file position.
>>> This gives you the size in units of "file storage units", which in the
>>> case of gfortran is 1 byte.
>>
>> If one assumes f2003 support such as unformatted stream, one might as
>> well also try the f2003 standard version of exactly the functionality
>> requested. I suppose it ought to be equivalent in most cases, but I'd
>> try the simpler version first.
>>
>> Namely, look at the size= specifier in the inquire statement, which
>> retrieves "the size of the file in file storage units."
>
> Ah, you're right. I forgot about this feature of inquire. And yes,
> size= works as of gfortran 4.4.
>

Indeed

integer(kind=8) :: fsize
inquire(file=filename,size=fsize)

works for me with gfortran 4.6 but not with gfortran 4.4.3 provided by
Ubuntu. In this case I get the value -1.

Thanks
JBF

--
Seuls des formats ouverts peuvent assurer la pᅵrennitᅵ de vos documents

Erik Toussaint

unread,
Nov 22, 2010, 7:31:12 AM11/22/10
to
On 20-11-2010 1:55, James Van Buskirk wrote:
>
> A word of caution: there is a difference between:
>
> character(kind=C_CHAR)
>
> and:
>
> character(C_CHAR)
>
> For character type declarations remember that LEN is positioned
> before KIND. This is part of gfortran PR 46496.
>

A mistake so easy to make, that even Metcalf, Reid & Cohen make it in
one place (that I know of) in 'fortran 95/2003 explained' (cf. paragraph
18.7.3 'ISO 10646 character set').

Erik.

robin

unread,
Nov 21, 2010, 11:58:21 PM11/21/10
to
"Richard Maine" <nos...@see.signature> wrote in message news:1js8euo.lu0s2y1rzpa8N%nos...@see.signature...
| glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
|
| > OK, but what do you think about the PL/I method. Not that it
| > would have been possible to graft into Fortran, but just for
| > comparison purposes. In PL/I, all declarations specify the
| > desired precision, and, for fixed point the scale factor
| > (position of the radix point). Some of the popular declarations
| > are FLOAT DECIMAL(15), or FLOAT BINARY(23) for floating point,
| > and FIXED BINARY(31,0) for fixed point.
|
| I don't like it at all. For a start it is verbose. I far prefer putting
| the verbosity in a parameter. That's particularly so when the verbose
| bits do not obvioously relate to my requirements. As you noted yourself,
| those "magic numbers" relate more to the representations of particular
| systems rather than to what users directly think of as requirements. I
| used to do some PL/I and I distinctly recall those "magic numbers" as
| meaning very little to me other than that 15 was how I asked for double
| precision. If one ever did port to a mchine where 15 wasn't a good
| number, you;d have to fix it up all over the code.

Here's a way that it could be done back then:-

%declare r15 character;
%r15 = 'float (15)';

declare k r8;

It can also be done this way now with a DEFINE statement :-

define alias r15 float (15);
declare x type r15;


Richard Maine

unread,
Nov 22, 2010, 12:48:31 PM11/22/10
to
Jean-Baptiste Faure <jean-bapt...@cemagref.fr> wrote:

> Le 19/11/2010 19:57, JB a écrit :
> > On 2010-11-19, Richard Maine<nos...@see.signature> wrote:

> >> If one assumes f2003 support such as unformatted stream, one might as
> >> well also try the f2003 standard version of exactly the functionality

> >> requested...


> >> Namely, look at the size= specifier in the inquire statement, which
> >> retrieves "the size of the file in file storage units."
> >
> > Ah, you're right. I forgot about this feature of inquire. And yes,
> > size= works as of gfortran 4.4.
>
> Indeed
>
> integer(kind=8) :: fsize
> inquire(file=filename,size=fsize)
>
> works for me with gfortran 4.6 but not with gfortran 4.4.3 provided by
> Ubuntu. In this case I get the value -1.

Ok. Well, at least the -1 is a standard-conforming implementation,
albeit unhelpful. Might be that someone had started putting it in, but
hadn't finished the job, or perhaps didn't get it done for all ports.
The -1 is what you are supposed to get if the size can't be determined
(or words very close to that).

As usual for the standard, it is completely up to the vendor what "can't
be determined" means. "Didn't get around to that yet" is as valid a
meaning as any.

If nothing at all had been done about the feature, I'd expect a
compilation error.

JB

unread,
Nov 22, 2010, 3:02:55 PM11/22/10
to
On 2010-11-21, James Van Buskirk <not_...@comcast.net> wrote:
> BTW, when gfortran breaks binary compatibility in a big way with
> new array descriptors, is it also going to switch to 64-bit hidden
> CHARACTER LENs on 64-bit platforms like ifort?

IIUC the original decision to go with the C "int" type (or,
INTEGER(kind=4) in gfortran) was done because

1) A lot of C-Fortran cross-language code (pre-ISO_C_BINDING) used C
int to specify the character length. Presumably because that's what
g77, and maybe other compilers as well, did.

2) Little or no legitimate need for > 2 GB characters.

AFAIK there has been no discussion to revisit this issue. But, if you
think it would be worthwile to change this, please do open a PR and
document whatever reasons you might have for wanting this change.

--
JB

James Van Buskirk

unread,
Nov 22, 2010, 3:50:41 PM11/22/10
to
"JB" <f...@bar.invalid> wrote in message
news:slrnielj3...@kosh.hut.fi...

> On 2010-11-21, James Van Buskirk <not_...@comcast.net> wrote:

>> BTW, when gfortran breaks binary compatibility in a big way with
>> new array descriptors, is it also going to switch to 64-bit hidden
>> CHARACTER LENs on 64-bit platforms like ifort?

> IIUC the original decision to go with the C "int" type (or,
> INTEGER(kind=4) in gfortran) was done because

> 1) A lot of C-Fortran cross-language code (pre-ISO_C_BINDING) used C
> int to specify the character length. Presumably because that's what
> g77, and maybe other compilers as well, did.

Since a Fortran CHARACTER variable looks more like an array of char
than anything else in C, its LEN should be size_t in C or
INTEGER(C_SIZE_T) in Fortran. Doesn't C code that uses int where
size_t is the legitimate expectation assume responsibility for
breakage on 32- to 64-bit transition?

> 2) Little or no legitimate need for > 2 GB characters.

But there is an issue of packing LEN values in structures and when
you do that in a less than pedantic way you start to break binary
compatibility. Besides, shouldn't your genome fit in a CHARACTER
variable, or specification variables:

CHARACTER(specification_function_1(dummy_argument)) sv1(0)
CHARACTER(specification_function_2(LEN(sv1,KIND=8))) sv2(0)

be able to use their LENs to store values > 2**31-1?

> AFAIK there has been no discussion to revisit this issue. But, if you
> think it would be worthwile to change this, please do open a PR and
> document whatever reasons you might have for wanting this change.

I tried to file a PR once and there was some issue that cropped up,
I can't remember whether it was signing over all my I.P. to the F.S.F.
or a potential torrent of spam from the mailing list that stopped me,
but there was some showstopper in there so the way I try to get bugs
reported is by talking about them in a public forum such as this one.
I realize that many if not all gfortran developers don't like it when
I do this but please understand that I'm only trying to help you make
a good project better in the only way that I know how.

There is another issue about binary compatibility with gcc and
gfortran, and I tried to find it on the mingw and gfortran web sites
but I'm just no good at searching them so I gave up on it.

glen herrmannsfeldt

unread,
Nov 22, 2010, 5:14:56 PM11/22/10
to
James Van Buskirk <not_...@comcast.net> wrote:
(snip on character variable lengths)

> But there is an issue of packing LEN values in structures and when
> you do that in a less than pedantic way you start to break binary
> compatibility. Besides, shouldn't your genome fit in a CHARACTER
> variable, or specification variables:

No, whole chromosomes should, though. For people, that is about
250MB for Chromosome 1. There is a member of the deer family
with only two chromosomes, but even there, each is less than 2GB.

There are some plants with vary large genomes, but I believe
with many chromosomes, and not excessively long. Still, there could
be some out there >2GB.

(Note that it is common to store genome data one ASCII character
per base, instead of the two bits needed. It will then compress
down with many compression algorithms.

-- glen

David Duffy

unread,
Nov 22, 2010, 6:23:13 PM11/22/10
to
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

> (Note that it is common to store genome data one ASCII character
> per base, instead of the two bits needed.

Nit, have to encode base deletions, and sometimes other bases, so actually
need 3 :)

glen herrmannsfeldt

unread,
Nov 23, 2010, 4:03:22 AM11/23/10
to
Richard Maine <nos...@see.signature> wrote:
(snip on matching actual and dummy argument types)

>> > Either that or you are going to have to invent some kind of
>> > prioritization rule that people will need to memorize.

>> That is pretty much what Java does. Multiple methods with the
>> same name but different types are resolved using such rules.
>> I haven't tried to memorize them, though.

> Fun. :-( I'm a far bigger fan of having one very trivial rule for
> everything instead of something that people have to memorize. Enough
> people complain about the simple rule; I hate to imagine trying to tell
> them to deal with a set of rules complicated enough that I hadn't even
> managed to memorize.

OK, the actual Java rules:

(For both overloaded methods and assignable primitive types.)

If two or more methods have the same name and have the same
number of parameters, choosing the correct method is more complex.
The compiler uses a "most specific" algorithm to do the match.

1. Find all the methods that could possibly apply to the invocation
-- namely, all the overloaded methods that ahve the correct name
and whose parameters are of types that can be assigned the values
of all the arguments. If one method matches exactly for all
arguments, invoke that method.

2. If any method in the set has parameter types that are all
assignable to any other method in the set, the other method
is removed from the set because it is less specific. Repeat
until no eliminations can be made.

3. If exactly one method remains, that method is the most specific
and will be invoked. If more than one method remains, the
invocation is ambiguous because there is no most specific
method, so the invoking code is invalid.

That is described in terms of overloaded classes, but it also
applies for assignable primitive types. Only widening assignments are
allowed, with byte --> short --> int --> long --> float --> double,
getting wider, in that order. (Preserving range but not necessarily
precision in, for example, long to float.) Also, char (which is
unsigned 16 bits) to int or wider.

So, like C89 Math.sqrt only comes in double, such that any other
primitive type can be converted to double and used with sqrt.

Math.min comes in (int,int), (long,long), (float,float), and
(double,double). Following the rules, for example,
Math.min(3,3.f) will be done as float, the int converted, and
the return value is float.

As an ambiguous example, if a method existed as (float,double),
(double,float), and (double,double), it would not be able to
be called with (float,float), as (double,double) is excluded
(less specific), and the other two are equally specific.

Narrowing assignments, or conversions on method calls,
require a cast.

-- glen

David Thompson

unread,
Nov 30, 2010, 12:17:09 AM11/30/10
to
On Sat, 20 Nov 2010 07:33:54 +0000 (UTC), glen herrmannsfeldt
<g...@ugcs.caltech.edu> wrote:

> Richard Maine <nos...@see.signature> wrote:
> > Daniel Carrera <dcar...@gmail.com> wrote:

<snip: call should convert to callee type>


> > And how would the compiler necessarily know about the dummy argument

> > (not parameter, as Steve noted)? Oh, you would have a system that was
> > different depending on whether the procedure interface was explicit or
> > not?
>
> That is what C and PL/I do. The Java rules are more complicated,
> especially with more than one parameter. (Recently my daughter
> started learning Java. She gets confused when I say argument,
> and mean parameter.) Java will promote to a wider type, if
> needed, without much complaint.
>
C yes. Java not really; any given Java method (routine) always has
exact types, though there can be overloads (like C++ and practically
equivalent to Fortran generics) as you discuss later.

The only semi-exception is Java's form of varargs, which unlike C only
allows variable _number_ not variable types. However, the fixed type
can be, and in popular cases like PrintWriter.format is, j.l.Object --
which is the ultimate superclass of every class (and interface) type,
and the only remaining types are the primitives (int, float, etc.)
which can (silently) be 'boxed' into j.l.Integer, j.l.Float, etc.
which are object types (thus passable to Object).

Aside: To avoid the cross-language 'argument' vs 'parameter' issue,
I like to use 'actual' and 'formal'. Note only does this have the
historical patina of dating to at least a68 and I think a60 (when
dinosaurs like Backus and Hopper and Hoare roamed the Earth) but to me
it is more directly mnemonic of the actual(!) difference.

> > Or, even with explicit interfaces, how about generics where there might
> > be specifics for multiple different kinds? That is quite typical of

> > generics, that being what they most commonly are for. If you are going
> > to select which specific to use based on the kind of the actual
> > argument, but select the kind of the actual argument based on which
> > specific gets used, you have a problem. Either that or you are going to


> > have to invent some kind of prioritization rule that people will need to
> > memorize.
>
> That is pretty much what Java does. Multiple methods with the
> same name but different types are resolved using such rules.
> I haven't tried to memorize them, though.
>

Added downthread. Yes, these are awkward to formalize, although they
do usually work intuitively for me, and apparently others.

glen herrmannsfeldt

unread,
Nov 30, 2010, 6:27:31 PM11/30/10
to
David Thompson <dave.th...@verizon.net> wrote:
(snip regarding argument type conversion)

>> That is what C and PL/I do. The Java rules are more complicated,
>> especially with more than one parameter. (Recently my daughter
>> started learning Java. She gets confused when I say argument,
>> and mean parameter.) Java will promote to a wider type, if
>> needed, without much complaint.

> C yes. Java not really; any given Java method (routine) always has
> exact types, though there can be overloads (like C++ and practically
> equivalent to Fortran generics) as you discuss later.

Java will, for example, promote to double any numeric type.
There is only one Math.sqrt(double), which can be used for double,
float, long, int, short, char, or byte arguments.

C, until C99, only had (double) for many math library routines,
and, given the prototype, arguments are converted.

PL/I generic intrinsic processing figures out if an appropriate
routine isn't available, and uses one that is. Usually converting
FIXED to FLOAT, but it will do many others, including CHAR to FLOAT.
If you do sqrt('2') it will give you the square root of two in
double precision.

Is Fortran the only language that doesn't allow generic intrinsic
routines to convert from types not available?



> The only semi-exception is Java's form of varargs, which unlike C only
> allows variable _number_ not variable types. However, the fixed type
> can be, and in popular cases like PrintWriter.format is, j.l.Object --
> which is the ultimate superclass of every class (and interface) type,
> and the only remaining types are the primitives (int, float, etc.)
> which can (silently) be 'boxed' into j.l.Integer, j.l.Float, etc.
> which are object types (thus passable to Object).

The rules, which I thought I posted somewhere in this thread,
work for either class/subclass relationships or widening promotions
for primitive types. If there isn't an unambiguous best match
then the compilation fails.


> Aside: To avoid the cross-language 'argument' vs 'parameter' issue,
> I like to use 'actual' and 'formal'. Note only does this have the
> historical patina of dating to at least a68 and I think a60 (when
> dinosaurs like Backus and Hopper and Hoare roamed the Earth) but to me
> it is more directly mnemonic of the actual(!) difference.

I suppose I am against this, as the use of an adjective in place
of a noun. Though not quite as much as the application program
--> application --> app transformation.

-- glen

0 new messages