named constants

It is now exactly two years that I wrote about the underestimated register keyword in C. Today I’d like to tell about an idea that is spinning in my head ever since, that register variables in file scope would be a perfect tool to offer a feature that is much missed in C: named constants of arbitrary data types.

The whole of it is a bit technical, be warned, but the essence of it will be to declare something like the following in a header file, without creating linkage or “instantiation” problems, and helping us to write readable and debuggable code:

register const double PI = 3.14159265358979323846;

typedef struct listElem listElem;
struct listElem { unsigned val; listElem* next; };

register const listElem singleton = { 0 };

Continue reading “named constants”

type generic functions taking pointers or arrays

Every C programmer knows about the implicit conversion an array object A undergoes in most contexts: it is converted to a pointer to its first element, as if the programmer had written `&A[0]`. The technical term of the standard for that is “lvalue conversion”, and the corresponding section describes what precisely is going on when an object (an lvalue) is evaluated for its contents (the rvalue).

One particular place where this conversion takes place is when an array is passed as an argument to a function. So in that case all additional information about the array, in particular its length, is not made available to the function. One could always pass the size of the array (sizeof A) as additional argument to the function, but this then would always require to pass this information also in case the function is called with what its interface suggest, just a pointer. In this post I will describe a new possibility that is provided by the _Generic keyword in C11 that allows us to create type generic interfaces that knows how to distinguish between the case being called with an array or with a pointer as an argument.
Continue reading “type generic functions taking pointers or arrays”

C11 defects: underspecification of tss_t

Section 7.26.6 “Thread-specific storage functions” of C11 is severely underspecified since it uses terms that are not introduced (so far) in the context of C. This is really a pity, since POSIX also has pthread_key_t that is completely feature equivalent and for which the specification is much more complete.

Jacob Navia had observed that at several occasions in comp.std.c but it seems that he had not got enough attention such that this had made it in a defect report.

Continue reading “C11 defects: underspecification of tss_t

C11 defects: initialization of atomic_flag

With this post I will be starting some random collection of things that I consider being defects of the C11 standard. Perhaps someone of the committee could pick them up or send me a mail to discuss them and eventually formulate a formal defect report.

C11 expresses the intention to have atomic_flag as a primitive that should allow to emulate all other atomic types and operations, 7.17.8 p3 in a note says:

The remaining types can be emulated with atomic_flag, though with less than ideal properties.

Continue reading “C11 defects: initialization of atomic_flag

C data model, simplified view

As we have seen in the earlier post, if you dig deeper into it the C data model is quite complex and has corner cases that are a bit bizarre. This might make C weirder than it need to be at a first approach.

As I said, the two most important properties of objects (or values) in C are if they are mutable (or not) and if they are addressable (or not), leaving us with 4 principal categories of objects that we have to deal with.

Continue reading “C data model, simplified view”

the C data model

For beginners in C the different terms that C applies to data items are often confusing. There are variables, literals, integer constants, compound literals, expressions, lvalues, rvalues… In this post I will try to put a bit of systematic into this and at the end move towards a simplified model.

First of all any sort of data in C usually has a type and a value. For example the literal 0 has the type signed int, 0u is unsigned int and 0.0 is double. But other kind of data may have different properties, e.g variables may be modifiable and may be scoped, some data has an address in memory and some doesn’t, etc.

Continue reading “the C data model”

try, throw and catch clauses with P99

Before C11 implementing try/throw/catch clauses with C alone was difficult. C lacked three features for that. First, there was no clear concept of threads. A throw that wants to unwind the stack to a calling function would have to capture the nearest try clause on the stack by inspecting a global variable. If you are running in a threaded environment (which most people do theses days) this global variable would have to hold the state of all current try clauses of all threads. With the new feature of _Thread_local variables (or their emulation through P99_DECLARE_THREAD_LOCAL in P99) this is now easy to solve. We just need a thread local variable that implements a stack of states.

The second feature that is useful for such an implementation are atomic operations. Though we can now implement a thread local variable for the stack of states, we still have to be careful that updates of that variable are not interrupted in the middle by signal handlers or alike. This can be handled with atomic operations, P99 also emulates the _Atomic feature on common platforms.

The third ingredient is _Noreturn. For C11 we can specify that a certain function will never return to the caller. This enables the compiler to emit more efficient code for if a branch in an execution ends with such an noreturn function.

These three interfaces together with other features that had been already present in P99, made it straight forward to implement P99_TRY, P99_THROW, P99_CATCH and P99_FINALLY.

Continue reading “try, throw and catch clauses with P99”

surprising occurrence of identifiers in header files

I remember being stuck sometime ago because a system header at the time on the platform that I was using defined the undocumented identifier barrier. IIRC this even was a macro, which made the bug really hard to track, seemingly harmless code simply exploded.

Hopefully nowadays platform implementors are a bit more careful in not polluting the namespace, but still avoiding naming conflicts is not so easy. E.g inline functions are a useful tool when you want to expose small functions to all compilation units of a program. There is one pitfall, though, when it comes to naming conventions for their parameter names and local variables. If you get the name wrong, as in this simple example

inline double my_sin(double PHI) { return sinf(PHI); } 

other users of your code might encounter random problems if they define a macro PHI.
Continue reading “surprising occurrence of identifiers in header files”

Emulating C11 compiler features with gcc: _Atomic

The new support for atomic operations in C11 is probably the most useful one. Support for atomic instructions is present in all commodity processors since at least 20 years, but a standardized interface in one of the main programming languages was really missing. Up to now you always had to implement stubs for these operations in assembler. This by itself was not as difficult for a given platform, but writing platform independent code quickly became tedious.

P99 now has an emulation of parts of these features that allow you to use them in a preview for C11. This implementation mainly uses (again) extensions of the gcc family. It should even work for older versions of gcc that don’t implement their __sync_.. built-in.

Continue reading “Emulating C11 compiler features with gcc: _Atomic”

Emulating C11 compiler features with gcc: _Generic

Besides the new interfaces for threads and atomic operations that I already mentioned earlier, others of the new features that come with C11 are in reality already present in many compilers. Only that not all of them might agree upon the syntax, and especially not with the new syntax of C11. So actually emulating some these features is already possible and I implemented some of them in P99 on the base of what gcc provides: these are

  • static_assert (or _Static_assert) to make compile time assertions (a misnomer, again!)
  • alignof (or _Alignof) to get the alignment constraint for a type
  • alignas (of _Alignas) to constraint the alignment of objects or struct members. Only the variant that receives a constant expression is directly supported. The variant with a type argument can be obtained simply by alignas(alignof(T)).
  • noreturn (or _Noreturn) to specify that a function is not expected to return to the caller
  • thread_local (or _Thread_local) for thread local storage
  • _Generic for type generic expression.

The most interesting among them is probably the latter feature, type generic expressions.
Continue reading “Emulating C11 compiler features with gcc: _Generic”