On Wednesday, 10 May 2017 at 05:26:11 UTC, H. S. Teoh wrote:
        int myfunc(blah_t *blah, bleh_t *bleh, bluh_t *bluh) {
                void *resource1, *resource2, *resource3;
                int ret = RET_ERROR;

                /* Vet arguments */
                if (!blah || !bleh || !bluh)
                        return ret;

                /* Acquire resources */
                resource1 = acquire_resource(blah->blah);
                if (!resource1) goto EXIT;

                resource2 = acquire_resource(bleh->bleh);
                if (!resource1) goto EXIT;

                resource3 = acquire_resource(bluh->bluh);
                if (!resource1) goto EXIT;

                /* Do actual work */
                if (do_step1(blah, resource1) == RET_ERROR)
                        goto EXIT;

                if (do_step2(blah, resource1) == RET_ERROR)
                        goto EXIT;

                if (do_step3(blah, resource1) == RET_ERROR)
                        goto EXIT;

                ret = RET_OK;
        EXIT:
                /* Cleanup everything */
                if (resource3) release(resource3);
                if (resource2) release(resource2);
                if (resource1) release(resource1);

                return ret;
        }


In modern C and with GLib (which makes use of a gcc/clang extension) you can write this as:

gboolean myfunc(blah_t *blah, bleh_t *bleh, bluh_t *bluh) {
        /* Cleanup everything automatically at the end */
g_autoptr(GResource) resource1 = NULL, resource2 = NULL, resource3 = NULL;
        gboolean ok;

        /* Vet arguments */
        g_return_if_fail(blah != NULL, FALSE);
        g_return_if_fail(bleh != NULL, FALSE);
        g_return_if_fail(bluh != NULL, FALSE);

        /* Acquire resources */
        ok = acquire_resource(resource1, blah->blah);
        g_return_if_fail(ok, FALSE);

        ok = acquire_resource(resource2, bleh->bleh);
        g_return_if_fail(ok, FALSE);

        ok = acquire_resource(resource3, bluh->bluh);
        g_return_if_fail(ok, FALSE);

        /* Do actual work */
        ok = do_step1(blah, resource1);
        g_return_if_fail(ok, FALSE);

        ok = do_step2(blah, resource1);
        g_return_if_fail(ok, FALSE);

        return do_step3(blah, resource1);
}

Some random example of this style of coding: https://github.com/flatpak/flatpak/blob/master/common/flatpak-db.c

Reply via email to