-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Kind specification implicit from context #201
Comments
This is indeed one of the rather annoying and nasty surprises of Fortran's floating point handling. So, I for one would really appreciate a feature like this. I think the most irritating issue with the current behaviour is that real(8), parameter :: const2 = 1./3. yields 0.33333334326744080 At first I would have thought that the value should just be truncated and zero-padded, but I do realise that this would be as wrong as the current value. A quite nice summary of these issues can be found here: Currently, the only reliable way I found to deal with this is via compiler flags, especially if one deals with codes that contain bits and pieces from various sources (as is the case with a lot of Fortran codes especially). |
Yes. That could be one existing approach. However, this would only work if your code is using a consistent precision all around. I.e. mixed precision codes would be difficult to handle through compiler flags, or it could have some performance issues at least. Having this built-in the standard would clarify and make a lot of things easier. |
One question is to get this into the standard, where I can see objections about "backwards incompatibility". However, this issue I think can be completely fixed by a compiler that would warn or refuse to compile your first example. I just created an issue for this in LFortran: https://gitlab.com/lfortran/lfortran/-/issues/305 In general I would like LFortran to have a mode that is "pedantic" and does not allow such code. Similar with "implicit none" if you forget to specify it, it will refuse to compile your code. That way it will force you to write correct code (that will correctly work with other compilers today), without needing to change the standard. I believe that is the easiest way to get these issues fixed in practice. |
I sort of had this feeling that perhaps there could be some backwards incompatibility. However, I think that the backwards incompatibility is a "random" fluctuation of numbers (as shown in the prior example). You never know which numbers gets appended in double precision. Here the clarity is implicit.
Yeah, compiler flags for checking this would also be awesome
Yeah, you are probably right, but my feeling is that nobody does this by intent. And if so they can easily be explicit. I think this would save more code than it breaks, if it actually will break anything. :) |
For gfortran |
KIND inference implicitly from context can cause significant problems in terms of backward compatibility. The issue is really is with the KIND of REAL (and INTEGER) literal constants and arguments and results of intrinsic subprograms. A proposal such as #78 will be a good approach for Fortran. |
Could you give an example where this would cause significant problems? I have tried to think of one that is really a problem, but I can't come up with anything but "unintended" assignment as mentioned above. |
Sometimes legacy codes have strict restrictions on backwards compatibility, i.e. results may have to be reproducible to the last bit. That will not be fulfilled if the precision of the expression in the following example changes
|
But here, that is not explicit on what the code wants? If it truly wants bit-set reproduceability, they should do |
Is this something you want a PR describing? |
I think such a proposal would have more cons than pros. The current rule is consistent over the whole standard, i.e. the evaluation of an expression does not depend on the context where it appears. Easy to remember. If then many people would think that
should also be interpreted as
and will omit the |
@PierUgit I think probably the best bet is to have good compiler warnings. I personally always append |
I still don't think that the corner cases should hold back something that is consistently done wrong. And this is a major issue for fortran programs (and new programmers!). While your example is real, I think the majority of programs tend to do all operations in 1 precision. Another approach would be to say that all constants are doubles (like c). |
On the contrary, when considering changing a decades-old behavior one has to carefully browse all the cases that could be affected, including the corner cases. And this is particularly important for the legacy codes (but not only). Note also that I disagree on the "major issue": yes this is a gotcha for new Fortran programmers, but once you have been caught you learn and you don't do the same mistake again. I can see another case where an automatic promotion (one of your proposals) would be a problem:
Here I want a double precision accumulator but I don't necessarily want the whole Apart from the suggestion of @certik to enable compiler warnings when detecting for literal constants that may have insufficient precision, the only reasonnable solution I can see would be making mandatory the use of
was present |
My experience is not this, quite often I find problems in submitted code that is because people just forget, even though they are capable, and knowledgeable about these issues.
I agree that a compiler warning is a good thing to do. Sometimes breaking changes needs to be done to make life easier... ;) |
Note that Fortran 202Y will actually bring a solution here, by allowing to specify in the code what are the default kinds. See this proposal that has been approved at the june 2023 meeting: https://j3-fortran.org/doc/year/23/23-199r1.txt |
Problem
Currently
real
are by definition floating point values. So when assigning constants to a double precision you'll get conversion lossesthe output will be:
to much surprise of some users.
Current way
Users are forced to explicitly denote the important constants as proper kinds. I.e. simple integers or reals that are well defined may not be affected. The solution to the above would be:
note not all are needed.
This alters the output to:
Suggestion
One needs to distinguish the two situations.
Consider this:
in both the above cases
1.
and3.
should automatically be bumped to thekind=8
specification as noted in the parameter declaration and by use of onekind=8
Another benefit is that complicated inline math would be much easier to write without worrying about kind-specifications.
Note that all of the same considerations of the above should apply to
integer
andcomplex
data types.Breaking code
I hardly think this would break codes in undesirable ways. In fact, what it would do is ensure correct handling in many codes since the kind specification is not necessary in many cases any more. So results may change, but I would argue that there are no cases where one wants to do less precision math (on purpose) and store in higher precision variables.
The text was updated successfully, but these errors were encountered: