tech-toolchain archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Convenience macros to help linting the kernel



On Sun, Jul 20, 2008 at 17:07:52 +0000, David Holland wrote:

> On Sun, Jul 20, 2008 at 06:46:50AM +0400, Valeriy E. Ushakov wrote:
>  > PS: I would dearly love a variadic __USED(), so that instead of 
>  > 
>  > #define KERNEL_UNLOCK(all, lwp, ptr)                       \
>  >    do {                                            \
>  >            __USED(all); __USED(lwp); __USED(ptr);  \
>  >    } while (/* CONSTCOND */ 0)
>  > 
>  > one could write just
>  > 
>  > #define KERNEL_UNLOCK(all, lwp, ptr) __USED(all, lwp, ptr)
>  > 
>  > but as far as I can tell it's impossible to write.
> 
> Never say impossible :-)
> 
> static __inline void __use(int x, ...) { /* LINTED */ (void)x; }
> #define __USED(...) __use(0, __VA_ARGS__);
> 
> works with both lint and gcc, and doesn't generate any code with -O
> and higher, either.

Yeah, I thought of that.  I should have qualified my statememt with a
constraint "w/out using inline functions" :).


> However, we already have a different form of __unused in cdefs.h...

That's a bit different.

There are two kinds of "legitimately" unused variables, explicitely
unused function arguments and "potentially" unused arguments/variables
(can think of a better term at the moment).

E.g. 

  /* ARGSUSED */
  static void
  hpf1275a_wskbd_set_leds(void *self, int leds)
  {

          /* this keyboard has no leds; nothing to do */
          return;
  }

where function signature is set by the interface, so dropping unused
arguments is not possible.  That's the "explicitely unused" kind, and
that's where __unused should be used (no pun intended).

  hpf1275a_wskbd_set_leds(void *self __unused, int leds __unused)

(BTW, we should really teach lint about __attribute__((__unused__)) so
that both lint and gcc utilize the same information.  Lint's ARGSUSED
comment turns off all checks, which is not fine-grained enough.


OTOH, a variable can be "potentially unused" when macros come into
play.  E.g. depending on whether MULTIPROCESSOR is defined

  void
  exit_lwps(struct lwp *l)
  {
          int nlocks;

          KERNEL_UNLOCK_ALL(l, &nlocks);
          // nothing that uses nlocks
          KERNEL_LOCK(nlocks, l);
  }

nlocks may or may not be used.  For such cases a macro definition that
doesn't use some of its paramters needs a way to explicitely "consume"
it to prevent potential compiler/lint warnings, so such macros
currently use (void)(x); that shuts up gcc, but that doesn't shut up
lint.  __USED(x); is more explicit about its purpose and hides
gcc/lint/... specific details (and has the same length :).

SY, Uwe
-- 
uwe%stderr.spb.ru@localhost                       |       Zu Grunde kommen
http://snark.ptc.spbu.ru/~uwe/          |       Ist zu Grunde gehen


Home | Main Index | Thread Index | Old Index