More g-wrap bogosities

Rob Browning rlb@defaultvalue.org
Sun, 13 Jan 2002 12:02:21 -0600


Derek Atkins <warlord@MIT.EDU> writes:

> Why can't you just always add "(void)<varname>;" for every
> variable/argument and always initialize stuff?  Don't worry about
> whether the argument is used or not; just add a line for all of
> them.  As you say, g-wrap is already designed for the compiler to
> optimize away unused code, and any decent optimizer will certainly
> work around this construct....

Well, then this would mean that for every type that people want to
define (via gw:wrap-type), we'd have to 

  (a) require that in addition to all the other things they have to
      specify (i.e. c->scm-codegen, scm->c-odegen, c-destructor, etc,
      we'd also have to have them define an initializer).  Not a huge
      deal, but unnecessary -- the person defining the g-wrap type
      wrappers has to specify a pointless piece of information just
      because the C compiler isn't quite smart enough (see below).

  (b) we'd have to use these initializers for every wrapped arg, even
      though the initialization is a total waste of code because,
      unless there are errors, those initializations will be blown
      away in short order by the scm->c converters for each arg.

The big problem here is that the C compiler is just not smart enough
to know that these variables really aren't ever used without being
initialized, and if it can't figure that out, I don't trust it to
figure out that the initializations in (b) above are always pointless
and ignore them.

The real underlying problem is that the wrapper code looks kind of
like this:

  CType1 c_arg1;
  CType2 c_arg2;
  CType3 c_arg3;

  c_arg1 = scm_to_c_Type1(scm_arg1, &status_var);
  if(status_var != GW__ERR_NONE) {
    set_some_error_codes...;
  } else {
    c_arg2 = scm_to_c_Type2(scm_arg2, &status_var);
    if(status_var != GW__ERR_NONE) {
      set_some_error_codes...;
    } else {
     ...
     ...
          c_result = some_c_func_call(c_arg1, c_arg2, ...);
          if(status_var != GW__ERR_NONE) ...
     
    }
    /* c_arg2 post-call processing code, if any goes here (in same
       scope as pre code */
  }
  /* c_arg2 post-call processing code, if any goes here (in same
     scope as pre code */

  if(status_var == GW__ERR_NONE)
    return scm_result;
  else
    gw__handle_error(status_var, various, bits, of, data ...);

The reason for this structure is that we need a way to allow wrapped
type's generated code to handle conversion errors while still making
non-error cases reasonably fast.

In any case, as you can see, there's no way that any of the c_args can
be used without being initialized, but the compiler doesn't figure
that out so we just have to tell it -Wno-uninitialized.

There's a similar argument to be made for -Wno-unused.  As an example,
g-wrap doesn't have any idea what code a given type is going to
generate to convert its arguments back and forth, so g-wrap has no
idea, for example, if the code generated by all of the type conversion
code for a given function's argument types and return value type will
reference the error signalling variables.  Since it can't know that,
it has to declare them just in case.

"Fixing that problem" would quite possibly involve either making
g-wrap less flexible (in terms of what a type's code generators are
allowed to look like) or might make g-wraps internals more
complicated.

Either way, I haven't had a lot of time to make sure I can't think of
a better solution, but since the two -Wno arguments fix the problem,
I can't justify spending a lot more time thinking about it right now.
I've already used up my g-wrap time allocation for a while.  However,
if you can think of something better, that'd be great.

> Is it a lot of extra infrastructure to keep a list of all the
> variables and just output a set of 'compiler warning fixes' for them?

How would I keep a list of variables?  All g-wrap knows about a type's
code generators is that it calls them with some arguments, and they
return a string-tree of c-code that is dumped to C output files at the
right times.  Unless g-wrap's going to parse that C code, it can't
know what it's doing.

Actually, that's not entirely true -- at least for the error status
variables, g-wrap requires the types to access those indirectly, so in
theory it might be able to keep closer track, but off the top of my
head, I think doing so would require a non-trivial amount of extra
code, and the benefit doesn't really seem worth it yet.

> I still might take a look at g-wrap and see if I can supply a fix to
> output what I think will fix the warnings.

Cool.

If you need help understanding what's going on, just holler.  In
truth, I think the next best g-wrap expenditure of my time would be in
updating the documentation to reflect the overhaul.  The existing docs
are now nearly useless.

-- 
Rob Browning
rlb @defaultvalue.org, @linuxdevel.com, and @debian.org
Previously @cs.utexas.edu
GPG=1C58 8B2C FB5E 3F64 EA5C  64AE 78FE E5FE F0CB A0AD