Jens Gustedt's Blog

August 22, 2013

testing compile time constness and null pointers with C11’s _Generic

Filed under: C11, C99, language, P99, preprocessor, syntax — Jens Gustedt @ 13:23

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 __builtin_constant_p
  • 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.


March 2, 2012

the C data model

Filed under: C11, C99, language, syntax — Jens Gustedt @ 02:52

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.


February 21, 2012

try, throw and catch clauses with P99

Filed under: C11, C99, language, P99, syntax — Jens Gustedt @ 21:59

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.


January 2, 2012

Emulating C11 compiler features with gcc: _Generic

Filed under: C11, C99, language, P99, syntax — Jens Gustedt @ 16:58

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.

March 18, 2011

Statement unrolling with P99_FOR

Filed under: P99, syntax — Jens Gustedt @ 23:00

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.

February 12, 2011

const and arrays

Filed under: C99, P99, syntax — Jens Gustedt @ 09:29

Qualifying a type with const may have some surprises. Consider the following

toto A = { 0 };
toto const* p = &A;

where toto is an opaque typedef that we don’t control. The question would be if the initialization of p is valid or not? From the way I pose that question, you have probably guessed the answer: it depends.

February 2, 2011

Handling control flow inside macros

Filed under: C99, language, P99, preprocessor, syntax — Jens Gustedt @ 20:35

When people program macros that they want to be executed anywhere where a statement could be, they often use the

do {...} while(0)

construct. This construct has a big disadvantage in that it may change control flow in an unexpected way when you’d use it as a generic macro tool to collect statements:

January 9, 2011

don’t be afraid of variably modified types

Filed under: C99, language, P99, syntax — Jens Gustedt @ 14:47

This post is about a subject that easily triggers a lot of polemic and diverging opinions, so I will try to be careful to get things right. In any case the message of this post may be summarized as:

  • Plain variable length arrays (VLA) might be dangerous for your health, since they may cause stack overflows, and generally are not so easy to handle
  • In constrast to that pointers to VLA are a quite different story and may ease the programming with multi-dimensional arrays substantially.


December 12, 2010

assignment and initialization

Filed under: C99, language, P99, syntax — Jens Gustedt @ 04:45

The innocent like character = has two different meanings in C, assignment and initialization. Unfortunately this difference is somehow not very pronounced and leads to confusion and inappropriate use. Many hard to track bugs are caused by lack of proper initialization.

November 29, 2010

Myth and reality about inline in C99

Filed under: C99, language, P99, syntax — Jens Gustedt @ 17:32

There is a very common misunderstanding about the inline keyword in C99. Rumors go that this would just be a useless hint to the compiler, that generation of external symbols or not is left to the compiler implementor, that this is some bizarre take over from C++ or whatever.

None of that is completely correct.

Older Posts »

Blog at