Why we hate C: sizeof() is evil.


Compiles clean (or should) with: gcc -o sizeof-test sizeof-test.c -Wall

#include <stdio.h>

typedef struct test {
    int a;
    char b[4];
} test;

int main(int argc, char **argv) {
    test a, *b;
    char c[100];
    char d[10][100];

    printf("sizeof(a): %d\n", sizeof(a));
    printf("sizeof(b): %d\n", sizeof(b));
    printf("sizeof(*b): %d\n", sizeof(*b));
    printf("sizeof(c): %d\n", sizeof(c));
    printf("sizeof(*c): %d\n", sizeof(*c));
    printf("sizeof(d): %d\n", sizeof(d));

Running the above code returns (on 32-bit architectures):

sizeof(a): 8
sizeof(b): 4
sizeof(*b): 8
sizeof(c): 100
sizeof(*c): 1
sizeof(d): 1000

When you declare a pointer to an object, the variable size is the size of the pointer.
But when you declare an array of objects, the variable size is the size of the object times the number of objects, even though the declared variable is a pointer.

This leads to garbage like this all over the place:

#include <sys/time.h>
#include <stdio.h>

int main(int argc, char **argv)
    struct timeval tarray[10];

    printf("sizeof(struct timeval)      : %u.\n", sizeof(struct timeval));
    printf("sizeof(tarray)              : %u.\n", sizeof(tarray));
    printf("number of elements in array : %u.\n", sizeof(tarray) / sizeof(tarray[0]));

    return 0;

Resulting in:

sizeof(struct timeval)      : 8.
sizeof(tarray)              : 80.
number of elements in array : 10.

Damn it C, grow a foreach() construct!