Re: Some changes to autoconfiguration APIs

2021-08-07 Thread Mouse
> Also, is there some way to distinguish an integer valued attribute
> which is explicitly set to 0 from one which isn't set at all

Not using the initialized-struct paradigm; there is no way to tell the
difference between
(struct foo){...no mention of y...}
and
(struct foo){y=0, ...no mention of y...}
because they compile to the same bits.

This is actually an advantage of the method I sketched upthread of
using no-op functions for type-checking with a varargs API function:
"not provided" can be handled differently from "provided" regardless of
the value provided.

/~\ The ASCII Mouse
\ / Ribbon Campaign
 X  Against HTMLmo...@rodents-montreal.org
/ \ Email!   7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B


Re: Some changes to autoconfiguration APIs

2021-08-07 Thread Taylor R Campbell
> Date: Sat, 07 Aug 2021 22:59:02 +0700
> From: Robert Elz 
> 
> Date:Wed, 4 Aug 2021 17:52:46 -0700
> From:Jason Thorpe 
> Message-ID:  <68ff8737-f347-4a7f-960b-9e4a6ca9e...@me.com>
> 
>   | It addresses the concerns about compile-time type checking
>   | by using an anonymous structure constructed in-line
> 
> Is there something in the C definition of such things which guarantees
> that the un-init'd fields all get set to 0/NULL ?   Or is that just
> happening because of the "const" spread all over - which might be causing
> the compiler to allocate static storage, but which is not required of const?
> 
> Also, is there some way to distinguish an integer valued attribute which
> is explicitly set to 0 from one which isn't set at all (in which case we
> might want to default it to some other value) or do we only ever use
> attributes via various kinds of pointers (or perhaps never have any,
> anywhere ever, where 0 is a sensible value) ?

C11, Sec. 6.7.9 `Initialization', paragraph 19, p. 141:

  `The initialization shall occur in initializer list order, each
   initializer provided for a particular subobject overriding any
   previously listed initializer for the same subobject; all
   subobjects that are not initialized explicitly shall be initialized
   implicitly the same as objects that have static storage duration.'

And paragraph 10, p. 140:

  `If an object that has static or thread storage duration is not
   initialized explicitly, then:

  `--- if it has pointer type, it is initialized to a null pointer;

  `--- if it has arithmetic tpye, it is initialized to (positive or
   unsigned) zero;

  `--- if it is an aggregate, every member is initialized
   (recursively) according to these rules, and any padding is
   initialized to zero bits;

  `--- if it is a union, the first named member is initialized
   (recursively) according to these rules, and any padding is
   initialized to zero bits.'

So pointers are nulled and integers are zero'd here -- and const is
not relevant, nor does the storage for these objects actually have
static duration; it's just that the anonymous struct objects with
designated initializers are initialized the same way as if they did
have static storage duration.


Re: Some changes to autoconfiguration APIs

2021-08-07 Thread Jason Thorpe


> On Aug 7, 2021, at 8:59 AM, Robert Elz  wrote:
> 
> Is there something in the C definition of such things which guarantees
> that the un-init'd fields all get set to 0/NULL ? 

Yes, as part of designated initializers in C, omitted fields are initialized in 
the same manner as static storage.

-- thorpej



Re: Some changes to autoconfiguration APIs

2021-08-07 Thread Robert Elz
Date:Wed, 4 Aug 2021 17:52:46 -0700
From:Jason Thorpe 
Message-ID:  <68ff8737-f347-4a7f-960b-9e4a6ca9e...@me.com>

  | It addresses the concerns about compile-time type checking
  | by using an anonymous structure constructed in-line

Is there something in the C definition of such things which guarantees
that the un-init'd fields all get set to 0/NULL ?   Or is that just
happening because of the "const" spread all over - which might be causing
the compiler to allocate static storage, but which is not required of const?

Also, is there some way to distinguish an integer valued attribute which
is explicitly set to 0 from one which isn't set at all (in which case we
might want to default it to some other value) or do we only ever use
attributes via various kinds of pointers (or perhaps never have any,
anywhere ever, where 0 is a sensible value) ?

kre



Re: Some changes to autoconfiguration APIs

2021-08-07 Thread Jason Thorpe


> On Aug 7, 2021, at 8:12 AM, Taylor R Campbell 
>  wrote:
> 
>> Date: Wed, 4 Aug 2021 17:52:46 -0700
>> From: Jason Thorpe 
>> 
>>> On Aug 1, 2021, at 11:10 AM, Martin Husemann  wrote:
>>> 
>>> On Sun, Aug 01, 2021 at 07:57:20AM -0700, Jason Thorpe wrote:
 The situation hasn't changed.  I'm still waiting for concrete proposals.
>>> 
>>> The concrete proposal is backout - if there is no better idea how to deal
>>> with it properly.
>> 
>> I have reworked it on the thorpej-cfargs2 branch.  It addresses the
>> concerns about compile-time type checking by using an anonymous
>> structure constructed in-line with the help of a variadic
>> preprocessor macro (to save wear and tear on your fingers and
>> keyboard that might otherwise occur because of annoying boilerplate
>> syntax to construct the structure in-line).
> 
> Thanks, this looks much better!  No more objections from me.

Great, I’ll merge the branch today.

-- thorpej



Re: Some changes to autoconfiguration APIs

2021-08-07 Thread Taylor R Campbell
> Date: Wed, 4 Aug 2021 17:52:46 -0700
> From: Jason Thorpe 
> 
> > On Aug 1, 2021, at 11:10 AM, Martin Husemann  wrote:
> > 
> > On Sun, Aug 01, 2021 at 07:57:20AM -0700, Jason Thorpe wrote:
> >> The situation hasn't changed.  I'm still waiting for concrete proposals.
> > 
> > The concrete proposal is backout - if there is no better idea how to deal
> > with it properly.
> 
> I have reworked it on the thorpej-cfargs2 branch.  It addresses the
> concerns about compile-time type checking by using an anonymous
> structure constructed in-line with the help of a variadic
> preprocessor macro (to save wear and tear on your fingers and
> keyboard that might otherwise occur because of annoying boilerplate
> syntax to construct the structure in-line).

Thanks, this looks much better!  No more objections from me.


For future work (definitely not a blocker for this or netbsd-10 or
anything) it would be nice if we could incorporate typed interface
attributes rather than just strings that are copied & pasted into the
source code and never checked until runtime.  For example, in
files.usb we could have something like

define  usbdevif  { [port = -1], ... }

which would lead config(8) to generate

static struct ifattachargs
IA_USBDEVIF(struct usb_attach_args *args)
{
return (struct ifattachargs) {
.iaa_name = "usbdevif",
.iaa_args = args,
};
}

and in usb_subr.c the code would be

dv = config_found(parent, IA_USBDEVIF(), ...);

with everything here verified by the compiler at compile-time.
Shouldn't be much effort to implement this -- just local changes in
config(8).  (I did something similar in picopb, e.g.
 and
.)

A stretch goal would be to push the types into the attach function
too, e.g.

int
uwhatever_attach(device_t parent, device_t self,
struct usb_attach_args *uaa)
{
...
}

but that might take a bit more work.