First, I think one can (at least for most integer-to-integer
conversions), ignore this warning. It is not really a bad programming
style to do so - at least if one is cautious not to do it when it
matters. For instant "real(8) :: sq2 =sqrt(2.0)" is a bad idea because
one wasts precision.
> int8 = INT(1,KIND=8)
>
Secondly, doing "INT(1, kind=8)" does not really make "1" a 8-byte
variable but converts a 4-byte variable to an 8-byte variable. The
proper way is to use:
1_8
where "8" is the kind number. Analogously, one can use 1_4 (for
integer(4)) or 1.0_8 for real numbers. For real numbers, using
something like
integer, parameter :: dp = kind(0.0d0) ! effectively: dp = 8
and then
1.0_dp
is the recommend way of doing. Thus my square-root -2 example would be
best written as
sq2 = sqrt(2.0_dp)
For integers one could do the same, e.g.
integer, parameter :: i8 = 8
int8 = 1_i8
The advantage of using a constant like "dp" or "i8" is that one can
change it if needed.
Note that kind numbers "8" and "4" for 8-byte and 4-byte variables are
very common, but that the standard allows any positive integer and it
depends on the compiler which one is valid and has which length. For
instance the NAG compiler uses 1 and 2 instead of 4 and 8 (except with
"-kind=byte").
Tobias
On 11/05/2009 08:14 AM, fulvio ciriaco wrote:
> Is this the dark side of fortran(90|95) or is it a peculiarity
> of gfortran? Numeric constants do not burden programmers in other
> languages.
That is the burden of Fortran 66 or even older (Fortran I?) - except
that you do not have there the underscore-number syntax. But Fortran 66
definitely made a distinction between 1.0 = 1.0e0 and 1.0d0 where the
former is single precision ("real" = "real*4") and the latter is "double
precision" (= "real*8").
But that's also not different from other programming languages. In C
"123" is "int" - and not "long". And 1.0 is "double", while 1.0f is
"float" and 1.0l is "long double".
For strings, even Python makes a distinction between b"ABC" and u"ABC"
(hope I got the syntax right).
Often one does not care and result is the same independ whether 1, 1_8,
1.0, or 1.0_8 is used. But sometimes it matters. Note that in gfortran
the warning is not enabled by default.
> Some languages check if they are within constraints
> of the assigned variables, particularly in inizialization, but
> treat them otherwise like a literal.
>
I doubt that there are many languages where it is a constraint.
(Constraint means something invalid which the compiler *must* reject -
at least that's what "constraint" means in the ISO Fortran standard.)
Well, if you try
int8 = 214748364833
you get an *error* in gfortran as 214748364833 overflows. The problem
with warning is that it really depends whether one wants to see a
warning or not. This is highly nontrivial - I once wanted to reduce the
number of conversion warnings in gfortran, but I gave up as it was not
clear to me when one could really turn the warning off.
> A warning from
> int8=int4
> makes little sense
Why? You can overflow here - you may not care or you know that it cannot
happen, but the compiler cannot know it (in the general case).
> a warning from
> int8=1
> makes no sense at all.
>
For integer not, but how about
real8 = 0.1
? ("0.1" is not exactly representable in a binary floating point number.)
> Asking the programmer to ignore these warnings also makes
> no sense, since one raises the verbosity level because is looking
> for the cause of troubles and wishes to search the cause of his problem
> in the smallest amount of text.
>
Sorry, there is no other solution: You cannot have all: (a) no
unnecessary warning, (b) writing sloppy code with the (implicit) type
conversion, (c) warnings where it matters. Choose one, choose two but
you cannot get all three.
I think that the most reasonable usage of the conversion warning is the
following: Develop the code with the warning disabled (-Wno-conversion)
- and only once in a while turn on -Wconversion and go through the list
of warning and check whether any of them requires action. I usually
check real/complex(4) -> real/complex(8) and
real/complex(8)->real/complex(4).
There will be hundreds of unnecessary warnings, but there will be one or
two where you made a mistake.
Tobias
Only line 9 i.e. {b=0.1l;} issues a warning, and this is more or less
the philosophy behind my words.
For integers, the literal describes the number unequivocally, no need
to burden the programmer with suffixes, only overflow could bring
problems, but the compiler can check overflow in most cases.
For inprecise numbers, two cases hold:
-initialization poses no problem, it is like reading into the
number from a string;
-assignment and comparison is the problem, I do not know why line 8
issues no warning. In my opinion, implicit type conversion should
not appear in clean code.
Python, lisp, scheme and similar syntaxes are not relevant. Variables
are simply lexical bindings in these languages, there is nothing
like a double float variable, only double float values. You can change
representation only by explicit cast.
In SML, which is a strongly typed language
val a:Int32.int=0;
means the same as
val a=(0:Int32.int);
that is, 0 is a lexical representation for any value appropriate
for the left side.
Thank you for your patience
Fulvio
From: Tobias Burnus <bur...@net-b.de>
Subject: Re: INTEGER*8 usage