Statement unrolling with P99_FOR

Specifying code that does same or equivalent things to a list of variables, tokens, items or so is an important source of annoyance. It can easily make code unreadable and difficult to maintain. E.g consider the following

 
if ((b == a) && (c == a) && (d == a) && (e == a) && (f == a)) {
  /* all are equal, do something special */
} else {
  /* handle the base case */
}

Understanding what that expression does is difficult in one glance and updating it is error prone. Adding another variable, say g, to be tested may be simple but withdrawing a is a major operation.
Continue reading “Statement unrolling with P99_FOR

Advertisements

flexible array member

C99 allows to define a flexible array member as the last member of a struct, namely an array of undetermined length.

P99_DECLARE_STRUCT(package_head);
struct package_head {
   char name[20];
   size_t len;
   uint64_t data[];
};

Such a struct can then allocated on the heap with a suitable size such that the field data has as much elements as fit in the allocated space from the start of data onward. Usually one would allocate such struct with

package_head *a = malloc(sizeof(package_head) + 10 * sizeof(uint64_t));
package_head *b = malloc(sizeof(*b) + 12 * sizeof(b->data[0]));

Continue reading “flexible array member”

C99 conformance test

I have recently tested some compiler that are publicly available for their C99 conformance. Doing that I finally came up with a relatively simple file that tests the compiler side of the conformance, not the library. Most of what looked relatively good, with the notorious exception of inline support that I already have described in a different post: pcc and modern gcc do well, ancient gcc, tcc, icc and opencc pump symbols for inline functions in every translation unit, and clang has no standardized way of generating such a symbol.

Continue reading “C99 conformance test”