Arguments format
Polytropon
freebsd at edvax.de
Sat Apr 18 13:31:26 UTC 2020
On Sat, 18 Apr 2020 14:07:00 +0200, Paweł Jasiak wrote:
> Thanks for your response!
>
> On 17/04/20, Polytropon wrote:
> > On Fri, 17 Apr 2020 18:05:56 +0200, Paweł Jasiak wrote:
> > > 1. In sys/mips/mips/autoconf.c we have functions
> > >
> > > static void configure_first(dummy)
> > > static void configure(dummy)
> > > static void configure_final(dummy)
> > >
> > > and we are not using argument. We are having those functions also in
> > > ricv, arm, arm64, powerpc and x86 and in non of them we are using dummy,
> > > so maybe we can just remove it? Or if it is necessary why we don't mark
> > > it as __unused like in other functions?
> >
> > I haven't checked any further, but I could imagine that
> > is has to do with the requirement of those functions
> > being able - at least in their declaration - to accept
> > a parameter; the type void * is a "somewhat universal"
> > type. Note that the functions are being mentioned in
> > macros, such as
> >
> > SYSINIT(configure1, SI_SUB_CONFIGURE, SI_ORDER_FIRST, configure_first, NULL);
> >
> > in /usr/src/sys/powerpc/powerpc/autoconf.c which might
> > be the reason why there has to be a dummy parameter...
> >
> > Okay, further investigation. ;-)
> >
> > According to "man 9 SYSINIT", the definition is
> >
> > SYSINIT(uniquifier, enum sysinit_sub_id subsystem,
> > enum sysinit_elem_order order, sysinit_cfunc_t func,
> > const void *ident);
> >
> > and the type sysinit_cfunc_t is defined as
> >
> > typedef void (*sysinit_cfunc_t)(const void *);
> >
> > in /usr/src/sys/sys/kernel.h, so this is the reaon why
> > the configure_first(), configure(), and configure_final()
> > functions have to be "compatible".
>
> Thanks, I didn't really pay attention to SYSINIT but still don't
> understand why we don't mark the arguments as __unused.
If I remember correctly, __unused is an attribute primarily
intended as a hint to the compiler that says "the variable
probably will not be used", so the compiler won't issue the
corresponding warning message. So __unused is optional here,
what matters is that sysinit_cfunc_t in SYSINIT requires the
argument list of (void *). However, if the dummy argument is
not to be used, adding __unused would probably be a good
idea.
> > > 2. Above functions have strange definition for arguments.
> > >
> > > static void
> > > configure(dummy)
> > > void *dummy;
> > > {
> > > ...
> > > }
> > >
> > > Why we are not using
> > >
> > > static void
> > > configure(void *dummy)
> > > {
> > > ...
> > > }
> > >
> > > like in other places?
> >
> > That is not a strange format, it's an older dialect of C,
> > usually called "K&R C", where the definition of a function
> > typically is:
> >
> > return-type function-name(arg1, arg2, arg3, ...)
> > type arg1;
> > type arg2;
> > type arg3;
> > ...
> > {
> > function-body
> > }
> >
> > A convention also is to put the function's return type on
> > an individual line, so the function's name always starts
> > at column 1.
> >
> > See "man 9 style" for details.
> >
> > Still, this style is not being followed consistently:
> >
> > % grep "^configure_first" `find /usr/src/sys -name autoconf.c`
> > /usr/src/sys/x86/x86/autoconf.c:configure_first(void *dummy)
> > /usr/src/sys/arm64/arm64/autoconf.c:configure_first(void *dummy)
> > /usr/src/sys/arm/arm/autoconf.c:configure_first(void *dummy)
> > /usr/src/sys/riscv/riscv/autoconf.c:configure_first(void *dummy)
> > /usr/src/sys/sparc64/sparc64/autoconf.c:configure_first(void *dummy)
> > /usr/src/sys/powerpc/powerpc/autoconf.c:configure_first(void *dummy)
> > /usr/src/sys/mips/mips/autoconf.c:configure_first(dummy)
> >
> > Some use "K&R C" style, others use "ANSI C" style.
>
> Thanks, I know both styles and I was worried about mixing them.
Excellent. :-)
The primary reason probably is the age of certain code. Not
all code present in FreeBSD conforms to "man 9 style".
> > > 3. In sys/mips/mips/octeon_cop2.c we are having
> > >
> > > struct octeon_cop2_state *
> > > octeon_cop2_alloc_ctx()
> > > {
> > > ...
> > > }
> > > but it's declaration in sys/mips/include/octeon_cop2.h is
> > >
> > > struct octeon_cop2_state* octeon_cop2_alloc_ctx(void);
> > >
> > > Question is if we should change octeon_cop2_alloc_ctx() into
> > > octeon_cop2_alloc_ctx(void)?
> >
> > There is a difference between () and (void) which _might_ be
> > intended; however, prototype and declaration should in fact
> > have the same signature. If the argument is (), the function
> > will accept any parameters, including none ("any parameters
> > list"); if it's (void), the function will refuse to accept
> > any parameters ("emtpy parameter list"), which is explicit
> > for "it doesn't use any parameters".
>
> I know the difference again ;)
>
> % grep -nr "octeon_cop2_alloc_ctx"
> sys/mips/mips/vm_machdep.c:164: td2->td_md.md_cop2 = octeon_cop2_alloc_ctx();
> sys/mips/mips/vm_machdep.c:169: td2->td_md.md_ucop2 = octeon_cop2_alloc_ctx();
> sys/mips/mips/octeon_cop2.c:53:octeon_cop2_alloc_ctx()
> sys/mips/mips/trap.c:942: td->td_md.md_cop2 = octeon_cop2_alloc_ctx();
> sys/mips/mips/trap.c:995: td->td_md.md_ucop2 = octeon_cop2_alloc_ctx();
> sys/mips/include/octeon_cop2.h:208:struct octeon_cop2_state* octeon_cop2_alloc_ctx(void);
>
>
> I believe that all uses of the octeon_cop2_alloc_ctx function so I still
> don't understand why we have different signatures.
According to "man 9 style", argument names can be omitted in
the header files, so declaration and definition might "look
different", but are the same to the compiler and linker:
int foo(int a, void *b, char c, struct blah d)
{
...
}
int bar(void)
{
...
}
The "simplified prototype" in the header file becomes:
int foo(int, void *, char, struct blah);
int bar(void);
Only the types remain.
That would be consistent; the example you provided is
inconsistent; /usr/src/sys/mips/mips/octeon_cop2.c contains
the definition as follows:
struct octeon_cop2_state *
octeon_cop2_alloc_ctx()
{
return uma_zalloc(ctxzone, M_NOWAIT);
}
The header file /usr/src/sys/mips/include/octeon_cop2.h
defines:
struct octeon_cop2_state* octeon_cop2_alloc_ctx(void);
As I wrote about the meaning of () vs. (void), this might be
an occassion to suggest that probably (void) should be used
in both places. You could file a bug report for this. Also
note that according to "man 9 style", the * belongs to the
name:
struct octeon_cop2_state *octeon_cop2_alloc_ctx(void);
And similarly:
struct octeon_cop2_state *
octeon_cop2_alloc_ctx(void)
{
return uma_zalloc(ctxzone, M_NOWAIT);
}
I cannot imagine why two different signatures exist, but
you could ask the developers if there _is_ a reason to do so.
As I mentioned, it's not actually wrong, as () "anything"
allows (void) "nothing", but still it should match. And
the function is always called with _no_ arguments, so (void)
should be the correct thing to choose here.
--
Polytropon
Magdeburg, Germany
Happy FreeBSD user since 4.0
Andra moi ennepe, Mousa, ...
More information about the freebsd-questions
mailing list