[FFmpeg-devel] [PATCH] AAC: type puns for 16 bit floating point rounding

Måns Rullgård mans
Fri Dec 5 03:23:08 CET 2008


Uoti Urpala <uoti.urpala at pp1.inet.fi> writes:

> On Fri, 2008-12-05 at 00:16 +0000, M?ns Rullg?rd wrote:
>> Uoti Urpala <uoti.urpala at pp1.inet.fi> writes:
>> 
>> > On Thu, 2008-12-04 at 17:11 +0000, M?ns Rullg?rd wrote:
>> >> Uoti Urpala wrote:
>> >> > On Thu, 2008-12-04 at 14:22 +0000, M?ns Rullg?rd wrote:
>> >> >> That is only true in the reverse situation, i.e. when the
>> >> >> standard allows something but gcc misbehaves.  Then we have
>> >> >> no choice but avoiding the offending construct.  If gcc
>> >> >> happens to generate intuitively correct code for something
>> >> >> that is undefined by the standard, we should still not be
>> >> >> using that something.
>> >> >
>> >> > It's not that GCC "happens to" generate the correct result,
>> >> > but that it explicitly defines it will work.
>> >> 
>> >> Same thing.  GCC happens to define this one way.  Another
>> >> compiler may do it differently.  GCC is not the only compiler.
>> >
>> > It's not the same thing. There are things undefined by the standard
>> > which GCC currently happens to implement one way but which are "random"
>> > and shouldn't be trusted to stay that way or to work the same on other
>> > compilers. This case is not one of those.
>> 
>> You fail to see the point.  Assuming conforming compilers, all that
>> matters is the standard.  If specific compilers define specific
>> behaviour outside the scope of the standard, this behaviour should not
>> be relied upon, except when the code will never be compiled with
>> another compiler, e.g. gcc-style inline assembler.
>
> You've never had a point.

You never understood the point.  There is a significant difference.

> First you claimed that GCC just "happened to" generate a particular
> result. That was false; GCC explicitly defines the behavior.

>From a standards point of view there is no difference.  Things are
either in the standard or not.  Behaviour under aliasing is
undefined.  There is no more to it.  Code that is only ever compiled
with a single compiler, e.g. gcc, can of course make use of documented
features of that compiler.  Code intended to be reasonably portable
should avoid doing this.

> Then you changed the claim to "GCC defines it this way, but another
> compiler may just as well do it another way". That was false too;

There may not be a compiler in existence right now that does it
differently.  That does not preclude a compiler with different
behaviour being written tomorrow.  Would you like me to write one for
you?

> it's not an arbitrary thing that each compiler would be likely to
> pick randomly.

Yes, it is.  That is the meaning of UNDEFINED in the standard.

> Now you're making a strawman argument, implying that my opinion
> would be based on GCC behavior only (saying that "specific compilers
> define specific behavior" is not enough to do something).  That's
> also invalid; my opinion has never been based on GCC behavior only.

If your opinion is not based on gcc behaviour, which other compilers
did you examine?  So far you have named none, despite me asking
several times.

>> >> >> There is no telling what another compiler or a future version of
>> >> >> gcc might do.
>> >> >
>> >> > You can tell with reasonable certainty. GCC has explicitly
>> >> > defined that it will work. If you don't rely on that then you
>> >> > shouldn't rely on other compiler-defined behavior either
>> >> 
>> >> I endeavour not to.
>> >> 
>> >> > (like right shifting negative numbers, or casting unsigned to
>> >> > signed to get a negative result).
>> >> 
>> >> As I said before, that excludes some Cray systems.
>> >
>> > What does that have to do with hardware?
>> 
>> Where did I say anything about hardware.  For the purposes of this
>> discussion, the "system" includes the compiler and C library.
>
> Then why do you believe *that* compiler-defined behavior can never
> change, and why is code relying on it not subject to your requirements
> that you stated without any exceptions for practical cases?

Representation of numbers is implementation-defined.  This implies
that a compiler must make a choice and document it.  Furthermore,
using different representations would result in incompatible machine
code.  Changing the representation of numbers would require a change
of the ABI for the machine/OS, and this does not happen unnoticed.

Things left UNDEFINED by the standard, on the other hand, are free to
change arbitrarily between different compilers, versions of the same
compiler, or depending on compiler flags.  A change will not matter to
conforming code.  This is not just hypothetical.  Compilers do vary,
and gcc frequently changes the details of undefined aspects, often due
to changes in the optimiser.

In the specific case of type punning through unions, gcc makes some
kind of promise regarding the behaviour, but this does *not* imply
anything whatsoever for other compilers.

>> > A compiler is free to define those any way it wants on any hardware.
>> > And defining right shifting to produce the same result as first
>> > casting to unsigned and then shifting is likely as good a match for
>> > hardware as sign extension.
>> 
>> It is an assumed, and a reasonably so these days, in FFmpeg that
>> integers use two's complement representation, and that right shift of
>> a signed integer replicates the sign bit.  We also know these
>> assumptions to be true for all hardware/compiler variants we wish to
>> support.  Furthermore, the C99 standard specifies representation of
>> and operations on signed integers to be implementation-defined,
>> meaning that a compiler should behave in a consistent, documented
>> manner.
>> 
>> The effects of violating the aliasing rules are *undefined*.
>> Implementations are not required to document their behaviour, nor need
>> the behaviour be consistent.
>
> The C standard itself does not require that. However, because of how
> common such issues are in programs, the compiler writers do need to
> consider how to approach the issue and do need to make a consistent
> choice.

Again, I ask you to name the other compilers you have verified the
behaviour of.  Did you check even one?

>> > Also practically all floating point in FFmpeg relies on sane compiler
>> > behavior rather than any standard (FFmpeg assumes much more than is
>> > guaranteed by the C standard, but does not request standard IEEE
>> > behavior either and is not compiled according to that on x86 with any
>> > compiler I know of).
>> >
>> >> >> If there is any chance at all that it might fail, it should
>> >> >> not be done.
>> >> >
>> >> > Then you'll get nothing done.
>> >> 
>> >> There will of course always be mistakes, and we can never be sure we've
>> >> corrected them all.  However, we can make a good effort to avoid things
>> >> we *know* to be undefined.
>> >
>> > "Undefined by a particular standard" is not the _only_ measure.
>> 
>> Being defined by a relevant standard is a necessary, but not
>> sufficient, condition for something to be safely used.  Other
>> conditions include correct compiler support.
>
> As illustrated by the examples above there's lots of code in FFmpeg that
> is not defined by a standard. Do you want to have all of it removed?

Ideally I would want all such code to be either rewritten properly or
protected so as not to be compiled with unknown compilers.

> I don't know what your definition of the term "safely used" is, but it

I mean that the behaviour is documented either by the C standard or
for *every* compiler that will compile the code in question.

> is not necessary for everything to be defined by a standard.

No, but it must be defined by *something*.

> There should be *some* reason to believe that a piece of code works
> and will continue to work.

Yes, and that would be documentation.  You have provided none for
compilers other than gcc.

> That its behavior follows from the requirements of a standard is a
> common reason and often an easily verifiable one, but it's not the
> only possible one. Practically all programs have some parts not
> covered by standards; that doesn't mean they would be unreliable or
> hard to port.

On the contrary, programmes relying on undocumented/undefined
behaviours are both unreliable and difficult to port to a new
environment simply because there is no easy way to determine the
intended behaviour of the code.

>> > This case can be expected to work for other reasons
>> 
>> Such as?
>
> You already asked why I thought a compiler would be unlikely to use
> more strict rules.

You asserted that *no* compiler uses more strict rules.  You have yet
to provide any evidence supporting this claim.

> I replied, and then in response you wrote only nonsense about
> "seeing gcc as the centre of the universe" even though my reply was
> in no way specific to GCC.

Your reply merely regurgitated your old arguments about gcc doing it
this way or that and how it would be rude of someone to write a
compiler behaving differently.

> Now you're asking basically the same thing again?

It is natural to assume that by "other reasons" you meant reasons
other than those discussed so far, i.e. that gcc does it one way.  Do
you have any?

-- 
M?ns Rullg?rd
mans at mansr.com




More information about the ffmpeg-devel mailing list