[FFmpeg-devel] [PATCH] libavcodec/wmavoice.c: localvariablepowmight mask pow function

Måns Rullgård mans
Mon Jul 26 15:12:57 CEST 2010


"Axel Holzinger" <aholzinger at gmx.de> writes:

> On Mon, Jul 26, 2010 at 12:56 AM, M?ns Rullg?rd wrote:
>> "Axel Holzinger" <aholzinger at gmx.de> writes:
>> 
>> > On Mon, Jul 26, 2010 at 11:18 AM, Eli Friedman wrote: 
>> >> On Mon, Jul 26, 2010 at 1:27 AM, Axel Holzinger <aholzinger at gmx.de> 
>> >> wrote:
>> >> > Hi Eli et al,
>> >> >
>> >> > On Sun, Jul 25, 2010 at 9:41 PM, Eli Friedman wrote:
>> >> >> On Sun, Jul 25, 2010 at 12:18 PM, Axel Holzinger 
>> >> >> <aholzinger at gmx.de> wrote:
>> >> >> > The issue is that a local variable pow masks a 
>> >> >> >function pow and
>> >
>> >> >> > that hurts if powf - which is used in the scope of local 
>> >> >> > variable pow - is not a function but a macro using double 
>> >> >> > precision pow function.
>> >> >>
>> >> >> And I'm pointing out that such an implementation is not correct 
>> >> >> per C99.
>> >> >
>> >> > I read the standard and under 7.1.4 (1) it's stated that 
>> >> > standard headers may export function like macros. I don't see
>> >> > how this couldn't be correct C99. Could you please provide a 
>> >> > reference where it's stated that a function like macro is
>> >> > forbidden in a standard header (at least for powf)?
>> >> 
>> >> It's okay for powf to be a macro.
>> >> 
>> >> > Also Unix/Posix allows powf to be implemented as a macro:
>> >> > http://www.opengroup.org/onlinepubs/009695399/basedefs/math.h.html
>> >> >
>> >> >> > Besides taking the effort to apply and document a patch
>> >> >> > patch, what do you think stands against the patch?
>> >> >>
>> >> >> Simply that you haven't actually pointed to why this is 
>> >> >> necessary
>> >
>> >> >> other than the abstract possibility of a non-conforming 
>> >> >> implementation of math.h.
>> >> >
>> >> > As mentioned above, I can't see why such an 
>> >> > implementation would be non-conforming. Can you elaborate.
>> >> 
>> >> Per C99, 7.1.3p1 and p2, "pow" is only reserved for use as a macro 
>> >> name or a file-scope identifier.  Therefore, it's legal to 
>> >> use it as the name of a local variable in any context.  A specific 
>> >> case of this is that the construct in wmavoice.c is legal C99 code,
>> >> and is required to compile on any conforming C99 implementation.
>> >
>> > Perhaps you don't yet understand the problem. Yes, it is 
>> > legal to use pow as a local variable name. Yes, it is also legal that
>> > powf is defined in <math.h> as a macro. That does not mean that the
>> > code in wmavoice.c is required to compile. This is one of the more
>> > obscure and ugly consequences of macros.
>> >
>> > Specifically, if powf() is defined as a function-like macro in 
>> > <math.h>, its definition would most likely use the pow() 
>> > function. You can expect something like the following:
>> >
>> > #define powf(a,b) ((float)pow((double)(a),(double)(b)))
>> >
>> > It is entirely legal C99 to have this macro definition in <math.h>,
>> 
>> No, it is not.  Since 'pow' is not reserved for identifers 
>> with local scope, the header may not use it in any way which 
>> might be incompatible with such use of the identifier in 
>> application code.  If math.h were to implement powf() as a 
>> macro, it would have to define
>> __pow() as an alias for pow() and use this in the macro definition.
>> Identifiers starting with __ (double underscore) are reserved 
>> for any use, so this would not cause problems for any 
>> conforming application code.
>
> Fair enough, could you please point me to clause in the standard
> that documents this?

As Eli already pointed out, 7.1.3 would be a good place to start.

>> > and the consequence in wmavoice.c is that the local variable pow 
>> > prevents the function pow() from being visible to the powf() macro, 
>> > leading to a compilation error.
>> 
>> Did this actually happen to you, or are you simply trolling?
>
> As you may have already have noticed from other threads, I'm
> currently trying to build FFmpeg on MinGW32 with icl (Intel compiler
> for windows) as compiler. As Intel doesn't bring a complete library,
> but instead fall back on some of the MS headers, math.h of MS is
> used.
>
> In the x64 part powf is a function and in the x86 part powf is a macro
> using the double precision version pow.

Then those headers are not conforming to the standard.

> Now, if you are right that would be illegal for a standard lib
> header (not only for C99, but also for C89, which MS claims to be
> compatible with). Still they do - and belieive me I know your
> reluctance regarding MS - the patch doesn't add any code cluttering
> or #ifdef orgy, but solves this issue and potentially others.

It solves a non-issue.  If it becomes an actual issue, we will fix it.

>> > In general, if you use a function-like macro, you have to take care 
>> > not to redefine any of the identifiers that it uses in its definition 
>> > (unless you know exactly what you're doing). As the standard does not 
>> > specify what those identifiers are, you are essentially stuffed. In 
>> > practice, you can apply common sense and avoid using those identifiers 
>> > which are most likely to create trouble.
>> 
>> The standard _does_ reserve the __* namespace for 
>> implementation use, so those are the names such macros must 
>> use.  It is perfectly safe and predictable.
>
> I just looked at MinGW's math.h:
> #define isfinite(x) ((fpclassify(x) & FP_NAN) == 0)
>
> This would then also be illegal, because the usage of fpclassify would
> mask a local variable fpclassify.
>
> On my Kubuntu 9.04 in math.h I find
>
> #  define isgreater(x, y) \
>   (__extension__
>    ({ __typeof__(x) __x = (x); __typeof(y) __y = (y);
>       !isunordered (__x, __y) && __x > __y; }))
>
> This masks a local variable isunordered.

fpclassify() and isunordered() are standard macros defined in math.h,
making them reserved if that header is included.  The macros above are
thus perfectly legit.

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



More information about the ffmpeg-devel mailing list