[RFC] fix semicolon at the end of RTE_LOG_REGISTER_DEFAULT
Morten Brørup
mb at smartsharesystems.com
Mon Apr 22 17:24:43 CEST 2024
> From: Stephen Hemminger [mailto:stephen at networkplumber.org]
> Sent: Monday, 22 April 2024 17.14
>
> On Sat, 20 Apr 2024 09:48:24 +0200
> Morten Brørup <mb at smartsharesystems.com> wrote:
>
> > > From: Stephen Hemminger [mailto:stephen at networkplumber.org]
> > > Sent: Saturday, 20 April 2024 02.08
> > >
> > > The macro RTE_LOG_REGISTER_DEFAULT emits code for an initialization
> > > function. If a driver (and most do) adds a semicolon after the macro.
> > >
> > > RTE_LOG_REGISTER_DEFAULT(logtype_foo, INFO);
> > >
> > > Is equivalent to:
> > >
> > > int logtype_foo;
> > > static void __logtype_foo(void) {
> > > logtype_foo = rte_log_register_type_and_pick_level(name,
> > > RTE_LOG_INFO);
> > > if (type < 0)
> > > logtype_foo = RTE_LOGTYPE_EAL;
> > > };
> > > The problem is that extra semi-colon after the function.
> > >
> > > If code is built with highest level of warnings (pedantic),
> > > then it will generate a warning.
> > > warning: ISO C does not allow extra ‘;’ outside of a function
> > >
> > > This is a treewide fix for this.
> >
> > It seems weird omitting the semicolon when using this macro.
> >
> > How about using the same trick as RTE_INIT_PRIO():
> >
> > #define RTE_INIT_PRIO(name, priority) \
> > static void name(void); \
> > static int __cdecl name ## _thunk(void) { name(); return 0; } \
> > __pragma(const_seg(CTOR_PRIORITY_TO_SECTION(priority))) \
> > __declspec(allocate(CTOR_PRIORITY_TO_SECTION(priority))) \
> > _PIFV name ## _pointer = &name ## _thunk; \
> > __pragma(const_seg()) \
> > static void name(void)
>
>
> RTE_INIT_PRIO is what is causing the problem. My example comes from:
> RTE_LOG_REGISTER_DEFAULT() -> RTE_LOG_REGISTER_IMPL() -> RTE_INIT ->
> RTE_INIT_PRIO
>
> The last line is used as prefix before RTE_LOG_REGISTER_IMPL that defines
> the init function full expansion is:
>
> // from RTE_LOG_REGISTER_IMPL
> int logtype_foo;
> // from RTE_INIT_PRIO
> static void __logtype_foo(void);
> static int __cdecl __logtype_foo_thunk(void) { __logtype_foo(); return 0; }
> __pragma(const_seg(CTOR_PRIORITY_TO_SECTION(priority)))
> __declspec(allocate(CTOR_PRIORITY_TO_SECTION(priority)))
> _PIFV __logtype_foo ## _pointer = &__logtype_foo_thunk;
> __pragma(const_seg())
> static void __logtype_foo(void)
> // from RTE_LOG_REGISTER_IMPL
> logtype_foo = rte_log_register_logtype_foo_and_pick_level(__logtype_foo,
> RTE_LOG_##level);
> if (logtype_foo < 0)
> logtype_foo = RTE_LOGLOGTYPE_FOO_EAL;
> } // no ; here is allowed
>
>
OK.
Perhaps adding a dummy afterwards or moving the global "type" variable down would work:
#define RTE_LOG_REGISTER_IMPL(type, name, level) \
int type; \
RTE_INIT(__##type) \
{ \
type = rte_log_register_type_and_pick_level(name, RTE_LOG_##level); \
if (type < 0) \
type = RTE_LOGTYPE_EAL; \
} \
+ int __dummy_##type
Or:
#define RTE_LOG_REGISTER_IMPL(type, name, level) \
- int type; \
+ extern int type; \
RTE_INIT(__##type) \
{ \
type = rte_log_register_type_and_pick_level(name, RTE_LOG_##level); \
if (type < 0) \
type = RTE_LOGTYPE_EAL; \
} \
+ int type
More information about the dev
mailing list