Page MenuHomeFreeBSD

sys: Remove redundant type casting to sysinit_cfunc_t
Needs ReviewPublic

Authored by zlei on Fri, Dec 6, 4:40 PM.
Tags
None
Referenced Files
Unknown Object (File)
Thu, Dec 26, 12:05 AM
Unknown Object (File)
Wed, Dec 25, 11:38 AM
Unknown Object (File)
Wed, Dec 25, 7:17 AM
Unknown Object (File)
Thu, Dec 12, 7:14 AM
Unknown Object (File)
Thu, Dec 12, 7:11 AM
Unknown Object (File)
Wed, Dec 11, 4:27 PM
Unknown Object (File)
Tue, Dec 10, 1:21 AM

Details

Summary

The definition of macro SYSINIT has already done the type cast.

No functional change intended.

MFC after: 1 week

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped

Event Timeline

zlei requested review of this revision.Fri, Dec 6, 4:40 PM

BTW, why does SYSINIT() enforces the cast? Isn't it more correct to not cast in the macro, and allow a compiler to check that the function passed matches the type?

In D47940#1093320, @kib wrote:

BTW, why does SYSINIT() enforces the cast? Isn't it more correct to not cast in the macro, and allow a compiler to check that the function passed matches the type?

typedef void (*sysinit_cfunc_t)(const void *);

struct sysinit {
        enum sysinit_sub_id     subsystem;      /* subsystem identifier */
        enum sysinit_elem_order order;          /* init order within subsystem */
        STAILQ_ENTRY(sysinit)   next;           /* singly-linked list */
        sysinit_cfunc_t func;                   /* function */
        const void      *udata;                 /* multiplexer/argument */
};

#define C_SYSUNINIT(uniquifier, subsystem, order, func, ident)  \
        static struct sysinit uniquifier ## _sys_uninit = {     \
                subsystem,                                      \
                order,                                          \
                { NULL },                                       \
                func,                                           \
                (ident)                                         \
        }; 
..

#define SYSINIT(uniquifier, subsystem, order, func, ident)      \
        C_SYSINIT(uniquifier, subsystem, order,                 \
        (sysinit_cfunc_t)(sysinit_nfunc_t)func, (void *)(ident))

If no cast in the macro, when assign a function pointer, e.g. void func(char *) to sysinit member func, the compiler would generate warning ( clang 's -Wincompatible-function-pointer-types or gcc's -Wincompatible-pointer-types ).

The last commit that defines C_SYSINIT and SYSINIT is 12cb7f73a61e, which is committed at 1999 . I believe those days the compilers are not smart enough and do not have mechanisms such as C11's _Generic. An explicit cast eliminate the warning and should relief developers to do cast everywhere.

I'm planing to employ _Generic to enforce valid function pointers. With that then this explicit casting should also be avoided.

Let me explain my PoV.

There should be no cast in the SYSINIT() macros at all. Consumer must pass void (*)(void *) function pointer and void *-compatible arg to the macro. The initialization function shall do the required casts.

How many const void * cases do we have in the tree?

In D47940#1094028, @kib wrote:

Let me explain my PoV.

There should be no cast in the SYSINIT() macros at all. Consumer must pass void (*)(void *) function pointer and void *-compatible arg to the macro. The initialization function shall do the required casts.

Well, I'm experimenting the opposite, a more safe way, to avoid void (*)(void *) function pointer and void * arg. So initialization function does not have to cast.

How many const void * cases do we have in the tree?

Indeed only small amount, all are in sys/kern/init_main.c, introduce by my previous work on constify some runtime readonly global variables. I have plans to constify more, but I'd like to improve SYSINIT / C_SYSINIT firstly so I'll get convinced I'm doing the right. TUNABLE_INT is a good start, struct tunable_int s are runtime readonly.

# grep C_SYSINIT sys/kern/init_main.c | wc -l
9