[FFmpeg-devel] Moving if(constant expression) to preprocessor?
Axel Holzinger
aholzinger
Sun Sep 19 18:14:49 CEST 2010
M?ns Rullg?rd wrote:
> "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.
It's a library. Use what you like, let the rest stay away. Perhaps
just try it out and make your own experiences. But that's OT here.
> > They have a really nice preprocessor library.
>
> Boost and nice are mutually exclusive.
M?ns Rullg?rd and nice are mutually exclusive. Does this help?
> > 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
Here is the code that works and that's tested with gcc:
#define AV_COND_IIF(bit, t, f) AV_COND_IIF_I(bit, t, f)
#define AV_COND_IIF_I(bit, t, f) AV_COND_IIF_II(AV_COND_IIF_ ## bit(t,
f))
#define AV_COND_IIF_II(id) id
#define AV_COND_IIF_0(t, f) f
#define AV_COND_IIF_1(t, f) t
#define AV_COND_BOOL(x) AV_COND_BOOL_I(x)
#define AV_COND_BOOL_I(x) AV_COND_BOOL_ ## x
#define AV_COND_BOOL_0 0
#define AV_COND_BOOL_1 1
#define AV_COND_IF(cond, t, f) AV_COND_IIF(AV_COND_BOOL(cond), t, f)
Nothing is redefined.
> 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.
see above
Usage:
Before:
#define REGISTER_HWACCEL(X,x) { \
extern AVHWAccel x##_hwaccel; \
if(CONFIG_##X##_HWACCEL) av_register_hwaccel(&x##_hwaccel);
}
With the macro:
#define REGISTER_HWACCEL(X,x) { \
extern AVHWAccel x##_hwaccel; \
AV_COND_IF(CONFIG_##X##_HWACCEL,
(av_register_hwaccel(&x##_hwaccel)),) ; }
> However, it is far more convoluted than the current code
What?
> for no gain,
It makes it possible to completely disable optimisations. To date the
configure script offers to disable optimisations, but doesn't do so.
One could call this a bug, at least it relies on compiler specifics
that are not mandated by C99.
> and Reimar's comments are valid too.
I think Reimar's comments are beside the point. The only thing the
compiler does, if a runtime if is used instead of a macro, is that it
checks the syntax of the call, nothing else.
> > Isn't that sexy?
>
> No.
I think we might also disagree on real sexy girls.
Axel
More information about the ffmpeg-devel
mailing list