l4-hurd
[Top][All Lists]
Advanced

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

IDL issue


From: Jonathan S. Shapiro
Subject: IDL issue
Date: Sun, 08 Jul 2007 00:03:10 -0400

An issue has come up in defining the C binding for CapIDL, and I would
like input. The issue is not specific to capabilities.

Any IDL method returns two results: a result (error) code, and a return
value. [There may also be additional OUT parameters, but for my question
we can ignore those.]

The question is: should the C stub return the error code or the return
value?

Concrete example:

  idl:   float f(int arg);
  C:     float f(int arg, IDL_Env *_env);  [return result value]
  C:     result_T f(int arg, float *_retVal, IDL_Env *_env);
         [returns error code]

When the result value is returned, the error code is generally stored
into a dedicated slot within the IDL_Env structure.

In my opinion, returning the error code is better for two reasons:

  1. It leads to more consistent error checking:

       CHECKRESULT(f(arg, &retVal, &idlEnv));
       // where CHECKRESULT is a macro that may cause exceptional
       // control flow, and any code below this point can assume
       // the operation succeeded.

  2. It avoids an initialization problem. Consider the "return result
     type" idiom when an exceptional code is returned:

       float retVal = f(arg, &idlEnv);
       CHECKRESULT(idlEnv);

     note that if idlEnv.errorCode is non-OK, then the function took
     an exception and did not actually reply at all. Unfortunately,
     C requires that the procedure must return *something*, and the
     end result is that retVal gets assigned an uninitialized value.

     If the return value is a scalar (int, float, etc.) this is not
     too bad, but if it is a pointer or a structure it is really easy
     to get hurt badly by failing to check error results.

     In example [1], retVal is unchanged if an exception occurs. You may
     not have initialized it, but you did at least have a *chance* to
     initialize it.

For all of these reasons (and some others), Microsoft's DCOM design has
all interface methods returning an HRESULT, which is basically the error
code. This may be a matter of convention. .NET returns the return value,
but they rely on the fact that exceptions can be handled through the CLR
exception mechanism.

The early CORBA example binding went the other way. Procedures return
their return value, and error codes are returned via the IDL
environment. GNOME IDL followed this example, which means that we may
have a source-level compatibility issue to consider here.

I am honestly not sure what to do here, and I would appreciate input.
The bottom line, I think, is that *any* failure to check results is
potentially fatal in this type of code no matter which way the IDL is
generated. Either idiom can be maintained by a careful programmer.

If we choose to adopt the "return the return value" convention, it is
still necessary to handle capability returns specially in C, because the
caller must say where the incoming capability is to be stored (we cannot
get compiler help for this from an unmodified compiler).


Reactions/opinions?

-- 
Jonathan S. Shapiro, Ph.D.
Managing Director
The EROS Group, LLC





reply via email to

[Prev in Thread] Current Thread [Next in Thread]