Liste des Groupes | Revenir à c arch |
On 31/08/2024 21:08, Thomas Koenig wrote:Anton Ertl <anton@mips.complang.tuwien.ac.at> schrieb:>
Of course the fans of compilers that do what nobody means found a
counterargument long ago: They claim that compilers would need psychic
powers to know what you mean.
Of course, different compiler writers have different opinions, but
what you write is very close to a straw man argument.
What compiler writers generlly agree upon is that specifications
matter (either in the language standard or in documented behavior
of the compiler). Howewer, the concept of a specification is
something that you do not appear to understand, and maybe never
will.
An example: I work in the chemical industry. If a pressure vessel
is rated for 16 bar overpressure, we are not allowed to run it at
32 bar. If the supplier happens to have sold vessels which can
actually withstand 32 bar, and then makes modifications which
lower the actual pressure the vessel can withstand only 16 bar,
the customer has no cause for complaint.
As usual, the specification goes both ways: The supplier
guarantees the pressure rating, and the customer is obliged
(by law, in this case) to never operate the vessel above its
pressure rating. Hence, safety valves rupture discs.
That is very well put.
>
Specifications are an agreement between the supplier and the client.
The supplier promises particular functionality if the client stays
within those specifications. It is how things work in a huge range of
aspects of life. Sometimes there are agreements in place for what
happens if the specifications are broken (fine if you fail to deliver as
promised, jail sentence if you break the law, etc.), but these are
really just extensions of the agreement and specification.
>
If we think about computing, we can start with mathematics for examples.
A mathematical function maps one set onto another - it specifies what
value in the output set is produced from each value in the input set.
It does not specify the result for values that are not in the input set,
even if they are in a "reasonable" superset. So the real square root
function specifies an output for all non-negative real numbers - it does
not specify the result for negative real numbers. Attempting to find
the square root of a negative number is undefined behaviour.
>
Functions in computing are the same. You have a specification - a
pre-condition, and a post-condition. The inputs (including the
environment, if that is relevant) has to satisfy the pre-condition, and
then the function guarantees that the post-condition will hold after the
function call. Try to put anything else into the function without
satisfying the pre-condition, and it's garbage in, garbage out. If you
don't understand "garbage in, garbage out", you really don't understand
the first thing about software development. This has been understood
since the beginning of the programmable computer:
>
"""
On two occasions I have been asked, 'Pray, Mr. Babbage, if you put into
the machine wrong figures, will the right answers come out?' I am not
able rightly to apprehend the kind of confusion of ideas that could
provoke such a question.
"""
>
>
In the context of compilers, the specification is the language standard
in use at the time, combined with the specifications of any library
functions or other code being used. If you don't follow those
specifications - your input code does not meet the pre-conditions, or
the pre-conditions are not met when your code is run - you get undefined
behaviour. There is no rational way to expect any particular result
when the input is in essence meaningless.
>
>
So if there is a function (or operator, or other feature) specified by
the language or by library or function documentation, and you pass it
something that is not documented as fulfilling the pre-conditions, it's
garbage in, garbage out - your code is wrong. If your code makes
assumptions about the workings of a function that are not specified in
its post-condition, the code is wrong. It might work during testing,
but it is not guaranteed to work. If you try to use a function outside
its specifications, then your code is wrong.
>
>
Of course it is not always easy to make sure everything is correct
within specifications. Programming languages and libraries are
complicated, and people make mistakes. And where practical, it can be
good to take that into consideration - if it is possible to give error
messages or help in the case of bad inputs, then that can be very
helpful to people. But it doesn't make sense to try to give the "right"
output for wrong input. And it doesn't make sense to do this to the
significant detriment of efficiency with correct inputs.
>
To compare this to specifications in other walks of life, imagine an
electricity company. The specification they provide to you, the
customer, has the pre-condition that you pay your bills. The
post-condition is that you get electricity. If you break the
specification - you stop paying your bills - it's perfectly reasonable
that they cut off your electricity. But it is /nice/ if they first send
you warning letters, and offers to re-arrange your debt. But if you are
following the specifications and paying your bills, you would not want
the electricity company to keep providing electricity to those who don't
pay, because that would mean /you/ would have to pay more.
>
In the same way, I want my compiler to warn about potential problems or
undefined behaviour when it reasonably can, rather than jumping straight
to nasal daemons. But I don't want it to generate slower code that it
otherwise could, just because some people might write incorrect code. I
should not have to pay (in run-time efficiency losses) for other
people's potential failure to follow specifications.
>
But I am quite happy to have compiler options to control the balance and
behaviour. Compilers generally do little optimisation without flags
explicitly enabling them. And some compilers have flags to change the
language specifications (such as making signed integer arithmetic wrap).
There's not a lot they could do better to satisfy people who want the
tools to conform to their imagined specification rather than the actual
specifications.
>
I suppose one thing they could do is that when a new compiler version
comes out with new optimisations, they could have a flag that turns
these off even if you have enabled others. Maybe you could have
"-olimit=8" to say "limit optimisations to those in gcc 8". That might
give fewer surprises to people who have got their code wrong.
>
Les messages affichés proviennent d'usenet.