C tips (again)

bearophile bearophileHUGS at lycos.com
Fri May 1 07:40:18 PDT 2009


In the past I have probably already discussed about this link here:
http://users.bestweb.net/~ctips/

That site contains tips as precious as gold, even for non-C programmers.

You can easely see that those C tips (ctips) are written by a person that has a very large experience in programming C, more than most other person I have read about or met.

I have never appreciated the famous book by Kernighan&Ritchie about C (despite I use today still, mostly as a reference for the C std lib). But I have appreciated those ctips (that are almost a book) as soon I have seen that site.

So far about C I haven't found a book or site better than those ctips, if you know one of such references please tell me.

Those ctips are nice because they show many creative ideas (it shows things I have believed as nearly impossible/very hard to do with D).
I like those ctips also because it shows idioms that are at the same time:
- Low level (so they are usually very efficient, both in speed and final program size. And speed is one of the things that give power to a programmer);
- Designed to be used to create big systems, like to create C programs 100_000 lines long or more (so those idioms are designed to manage/kill high complexity);
- Designed to be write reliable software (so they are designed to avoid bugs. The C language is a very bug-prone language, but those ctips show ways to avoid or quickly hunt down most bugs).

Putting together speed (a kind of power) with anti-bug/anti-complexity makes those idioms almost universal for computers, so probably some of the ideas they rest on can be used in other low level languages beside C.

A problem is that even after reading those ctips two times, I am partially unable to keep them in memory and to use them. I have even troubles in copying them down from the site pages, because there are too many details to keep in memory, and because they are designed with an extreme rigorousness, like by an old Tibetan monk (on the other hand I am sure that if you want to write a 200K lines long C program, and you want a certain probability to see it actually run, you must use more rigor than I have ever used in my small programs). The author of those ctips can keep such idioms in memory because he has a ton of practice of C programming.

>From a certain point of view you can think of a medium/high level as D/Python/Ruby/Java as a collection of idioms of low level languages, that now you can use at high level (OOP can be seen as a collection of idioms in C. In old structured programming can be seen as an idiom. In the beginning even routines and functions were seen as idioms in assembly programming. There was even people that have discussed about the pro/cons of using routines!). That said, to design a good medium/high language (I consider D a medium level one) you must choose the right idioms, the best ones.

Those ctips are a collection of good low-level idioms. I think may be a good starting point to design a medium-level language (with power similar to C). So they can be useful to design part of D too. Currently D has already added some of those idioms.

--------------------

The following is a small example of one of those idioms, that I have used in a C program to have dynamic strings. I have seen that it's faster than alternative solutions like having a struct with size/capacity/pointer that points to a block of memory.

I have seen this idiom works in D too (and Mystring.sizeof == 8 still) but you can't use this idiom in D, you must always use -release.

This code is written by me, so it's NOT representative of the kind of code you can find in those ctips, my code is surely much worse.

This stuff is error-prone, and the author of ctips agrees with this. He never suggests to use things like this in this way. He suggests to add lot of other stuff here, to make this thing safer, sentinels to see if there are overflows, reflection means, more type flexibility, etc. You can't use ctips idioms half way, you have to use them fully, and this is NOT easy.

int max2(int a, int b) {
    return a > b ? a : b;
}

typedef struct { // sizeof(Mystring) == 8
    int size;
    int capacity;
    char data[0];
} Mystring;

Mystring* mystring_new(int capacity) {
    int new_capacity = max2((int)sizeof(int), capacity);
    int total_mem = sizeof(Mystring) + sizeof(char) * new_capacity;

    Mystring* str = malloc(total_mem);
    if (str == NULL) {
        printf("Error allocating %d bytes.\n", total_mem);
        exit(-1);
    }

    str->size = 0;
    str->capacity = new_capacity;
    return str;
}

Mystring* mystring_append_char(Mystring* str, char c) {
    assert(str != NULL && str->capacity > 0);
    if (str->capacity <= str->size) {
        // not enough space
        str->capacity *= 2;
        int new_total_mem = sizeof(Mystring) + str->capacity * sizeof(char);
        str = realloc(str, new_total_mem);
        if (str == NULL) {
            printf("Error allocating %d bytes.\n", new_total_mem);
            exit(-1);
        }
    }
    str->data[str->size] = c;
    str->size += 1;
    return str;
}


If you follow those ctips fully, you end having more reflection in such data structures than usually D gives you. That's why I have said it may be good to have many of those idioms as built-ins in a medium-level language.

Bye,
bearophile



More information about the Digitalmars-d mailing list