Skip to content
Alex edited this page Nov 21, 2018 · 3 revisions

Random references/notes I think will be useful.

C Related

Portable C

Definition (Urbanik). A "portable program" can be compiled and will run successfully on many different (a) compilers, (b) operating systems, and (c) hardware platforms with little or no change to the source code. (End of Definition)

From (one of these), I learned about perror which appears to be the same as fprintf(stderr, "%s\n", strerror(errno)) (SO).

Strings

Struct Inheritance

Strict aliasing rules denies us the ability to write:

struct base {
    int id;
    void (*calculate)(struct base *);
};

struct derived {
    int id;
    void (*calculate)(struct base *);
    double inflation;
};

void do_thing(struct base *a)
{
    a->calculate(a);
}

/* problem!!! */ 
void derived_calculate(struct derived *a)
{
    struct base *b = (struct base*)a;
    b->calculate(b);
}

The solution is to write:

struct derived {
    struct base super;
    double inflation;
};

Then casting (struct bar*)a works as expected; one just needs to be careful about struct packing. This conforms to the C standard (as Bob Nystrom noted):

§ 6.7.2.1 13

Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning.

Emphasis added.

ML

Type Inference/Checking

Type inference boils down to two steps: (i) constraint generation, (ii) unification. Put slightly differently: setting up equations, then solving them.

Clone this wiki locally