tech-kern archive

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

Re: KNF and the C preprocessor



On Mon, Dec 10, 2012 at 09:36:35AM -0600, David Young wrote:
>

> What do people think about setting stricter guidelines for using the
> C preprocessor than the guidelines from the past?  Example guidelines:
> 
> The C preprocessor MAY be used for
> 
> 1 Lazy evaluation: ...
> 2 Lexical manipulation: ...
> 3 Generic programming: ...
> 4 Computed constants.  ...

I would like to propose an additional, perhaps controversial, use.

5 Breaking the flow of control:

There are situations where I find that the error handling code
obsfucates the code substantially and that sometimes a quick macro
with a goto or return can render the code more readable.  As long
as this method is used sparingly, it can go a long way to make code
more readable especially in the case where there is a lot of memory
management.

As an example, I often define a macro when I am using Kerberos or
GSSAPI that looks roughly like:

#ifdef K5BAIL(x) do {
                ret = x;
                if (ret) {
                        /* format error message and whatnot
                         * in terms of #x.
                         */

                        goto bail;
                }
        } while (0)

This will allow me to write code like:

        K5BAIL(krb5_cc_default(ctx, &cache));
        K5BAIL(krb5_parse_name(ctx, princ, &server));
        K5BAIL(krb5_get_creds_opt_alloc(ctx, &opt));
        K5BAIL(krb5_get_creds(ctx, opt, cache, server, &out));
        K5BAIL(krb5_verify_init_creds(ctx, out, server, kt, NULL, NULL));

which you can quickly see exactly what I am doing, rather than:

        ret = krb5_cc_default(ctx, &cache);
        if (ret) {
                format error message;
                return ret;
        }

        ret = krb5_parse_name(ctx, &cache);
        if (ret) {
                format error message;
                krb5_cc_close(ctx, cache);
                return ret;
        }

        etc.

You can't do this with an inline function, because it can't use
goto or return.

Again, though, this method needs to be used sparingly and obviously (that
is, it should be obvious that you are doing it.)

--
    Roland Dowdeswell                      http://Imrryr.ORG/~elric/


Home | Main Index | Thread Index | Old Index