[FFmpeg-devel] Moving if(constant expression) to preprocessor?

Måns Rullgård mans
Sat Sep 18 19:23:17 CEST 2010


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

> M?ns Rullg?rd wrote:
>> "Axel Holzinger" <aholzinger at gmx.de> writes:
>> 
>> > Hi M?ns and all,
>> >
>> > M?ns Rullg?rd wrote:
>> >> "Axel Holzinger" <aholzinger at gmx.de> writes:
>> >> 
>> >> > Hi all,
>> >> >
>> >> > if compiling FFmpeg code with zero optimisations (even without
>> >> > dead code elimination) there are linker errors (undefined
>> >> > references to functions or structs) that come from constructs
>> >> > like i.e.  the following in libavcodec/allcodecs.c:
>> >> >
>> >> > if(CONFIG_##X##_HWACCEL) av_register_hwaccel(&x##_hwaccel); }
>> >> >
>> >> > The runtime (lower case) "if" leads to an undefined reference, 
>> >> > because it is evaluated at runtime and not at compile time.
>> >> >
>> >> > If dead code eliminitation optimisation is on, this isn't an
>> >> > issue, but with optimisations completely off it is.
>> >> 
>> >> > Then I would try and find a solution based on preprocessor magic.
>> >> 
>> >> That is not easily possible.
>> >
>> > Says who ;-)
>> 
>> Says I.
>
> And that has to suffice?

Yes.

>> > It is possible to write a macro that does the trick and in 
>> > the end the above line would for example look like this:
>> >
>> > AV_COND_IF(CONFIG_##X##_HWACCEL, (av_register_hwaccel(&x##_hwaccel)),)
>> 
>> How would AV_COND_IF be defined?
>
> Do you know boost?

I have encountered the monstrosity.

> They have a really nice preprocessor library.

Boost and nice are mutually exclusive.

> I got inspired by their BOOST_PP_IF macro.
>
> It's more generic as it would be needed here. So reduced to what's
> needed it could look like this (compiler specific #fdefs removed for
> clarity):

What compiler-specifics would be involved here?  FFmpeg uses only
standard C99 features in non-optional code.

> # define ICL_PP_IF(cond, t, f) ICL_PP_IF_I(cond, t, f)
> # define ICL_PP_IF_I(cond, t, f) ICL_PP_IIF(ICL_PP_BOOL(cond), t, f)
>
> #else
>
> #define AV_COND_IF(bit, t, f) AV_COND_IF_OO((bit, t, f))
> #define AV_COND_IF_OO(par) AV_COND_IF_I ## par

This is not valid C.  See C99 spec section 6.10.3.3 The ## operator:

  If the result is not a valid preprocessing token, the behavior is
  undefined.

You are attempting to concatenate the token AV_COND_IF_I with a left
parenthesis, which combination is not a valid single token.

> #define AV_COND_IF_I(bit, t, f) AV_COND_IF_I(AV_COND_IIF_ ## bit(t, f))
> #define AV_COND_IF_I(id) id

Quoting the spec again:

  [...] an identifier currently defined as a function-like macro shall
  not be redefined by another #define preprocessing directive unless
  the second definition is a function-like macro definition that has
  the same number and spelling of parameters, and the two replacement
  lists are identical.

> #define AV_COND_IF_0(t, f) f
> #define AV_COND_IF_1(t, f) t

I see what you are trying to do, but the way you are doing it does not
work.  With a few more layers of macros it would actually work, at
least in trivial cases.

However, it is far more convoluted than the current code for no gain,
and Reimar's comments are valid too.

> Isn't that sexy?

No.

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



More information about the ffmpeg-devel mailing list