Abandoned

Since infogami has been abandoned by its creators, I’m out too. Back to web.fisher.cx for me. Everything that was here is there.

Robert Fisher

Just thinking out loud

C idioms

If you register and log in you can add comments to my pages. If viewing the main blog page, click the # underneath an entry to comment on it.

Note...

  • ...the standard reserves identifiers with a leading underscore...
  • ...the standard reserves macros matching E[0-9A-Z]...

...for use by the standard or the implementation.

In particular, if should keep this in mind when automating the creation of header guards.

Bad:

#ifndef __EVERYTHING_H__
#define __EVERYTHING_H__
/* ... */
#endif

Also bad:

#ifndef EVERYTHING_H_
#define EVERYTHING_H_
/* ... */
#endif

Good:

#ifndef H_EVERYTHING
#define H_EVERYTHING
/* ... */
#endif

I find this pattern reoccuring (recursively) in C:

void example()
{
    resource_t r = get_resource();
    if(!r) {
        report_error();
    } else {
        do_interesting_stuff_with_resource(r);
        release_resource(r);
    }
}

It's nice to handle the error case first, because then the error handling is close to the point of error.


Fun with the comma operator:

if(!p) return fprintf(stderr, "%s: null pointer\n", __FUNCTION__), EINVAL;

Opaque pointers/handles

/* foo.h */
typedef struct foo_tag * foo_t;
extern foo_t make_foo(int);
extern int foo_get_value(foo_t);
extern void free_foo(foo_t);

/* foo.c */
struct foo_tag
{
    int value;
};

foo_t make_foo(int n)
{
    foo_t handle = malloc(sizeof(struct foo_tag));
    if(!handle) return 0;
    handle->value = n;
    return handle;
}

int get_foo(foo_t handle)
{
    if(!handle) return 0;
    return handle->value;
}

void free_foo(foo_t handle)
{
    if(handle) free(handle);
}

Pointer cast polymorphism

struct base_tag
{
    int base_field1;
    int base_field2;
};

struct derived_tag
{
    struct base_tag base;
    int derived_field1;
    int derived_field2;
};

struct derived_tag * derived = malloc(sizeof(struct derived_tag));
struct base_tag * base = (struct base_t *) derived; /* equivalent to &derived->base */

do {
    int error_code;

    error_code = some_function();
    if(NO_ERROR != error_code) break;
    /* ... */
} while(false);

Back to the Scheme & general programming main page