Let’s take the occasion of the change back from DST here in Europe, not in the US, yet, to look how times are handled in C.
The C standard proposes a large variety of types for representing times:
double and textual representations as
char. It is a bit complicated to find out what the proper type for a particular purpose is, so let me try to explain this.
The first class of “times” can be classified as calendar times, times with a granularity and range as it would typically appear in a human calendar, as for appointments, birthdays and so on. Some of the functions that manipulate these in C99 are a bit dangerous, they operate on global state. Let us have a look how these interact:
Continue reading “different times in C: calendar times”
Sometimes in C it is useful to distinguish if an expression is an “integral constant expression” or a “null pointer constant”. E.g for an object that is allocated statically, only such expressions are valid initializers. Usually we are able to determine that directly when writing an initializer, but if we want to initialize a more complicated
struct with a function like initializer macro, with earlier versions of C we have the choice:
- Use a compiler extension such as gcc’s
- We’d have to write two different versions of such a macro, one for static allocation and one for automatic.
In the following I will explain how to achieve such a goal with C11’s
_Generic feature. I am not aware of a C++ feature that provides the same possibilities. Also, this uses the ternary operator (notably different in C and C++), so readers that merely come from that community should read the following with precaution.
Continue reading “testing compile time constness and null pointers with C11’s _Generic”
A while ago I already have written about Linux futexes as a really nice concept for a control data structure that goes beyond the ones that we learn or teach in school (mutex, semaphore, condition variable…). I have now gone one step further and integrated futexes into P99; if used on Linux this will evidently use the corresponding Linux feature under the hood, on other platforms a C11 thread implementation using mutexes and condition variables can be used.
One of the real disadvantages of most of the control structures is that they have two very different kinds of events: user events (e.g a call to
cnd_signal) and system events, often called “spurious wakeups”. Unless we program system code, these spurious wakeups are just an annoyance. They are easily forgotten during development and lead to subtle bugs that only appear on heavy load or when changing the platform and handling them often makes the user code overly complex.
p99_futex are designed to work around this type of problems, by still providing a close integration of the control structure into the system and by efficiently distinguishing a “fast path” for operations from a “slow path” where we handle congestion. They provide a counter similar to a conditional variable that allows atomic increments and to wait for it, just as the Linux system call does. (Only that for ideological reasons the base type is an
unsigned, instead of an
int as in Linux.)
Continue reading “P99 futexes: non-blocking integer valued condition variables”
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`. 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”
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
These three interfaces together with other features that had been already present in P99, made it straight forward to implement
Continue reading “try, throw and catch clauses with P99”
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
Continue reading “Emulating C11 compiler features with gcc: _Atomic”
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) to make compile time assertions (a misnomer, again!)
_Alignof) to get the alignment constraint for a type
_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
_Noreturn) to specify that a function is not expected to return to the caller
_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”