Simple defer, ready to use

With this post I will concentrate on the here and now: how to use C’s future lifesaving defer feature with existing tools and compilers.

I have already talked several times about defer, the new feature that hopefully will make it into a future version of C. With this post I will concentrate on the here and now: how to apply that lifesaving feature with existing tools and compilers.

After briefly discussing the defer feature itself, again, I will show you a first implementation with gcc extensions, a second with C++ standard features and then I will discuss a new proposal with for defer that has a syntax that is a tiny bit more constraining than what you may have seen so far.

Continue reading “Simple defer, ready to use”

The C23 edition of Modern C

The C23 edition of Modern C is now available for free download from

https://hal.inria.fr/hal-02383654

And as before a dedicated page for the book may be found at

https://gustedt.gitlabpages.inria.fr/modern-c/

where you also may find a link to download the code examples that come with the book.

This new edition has been the occasion to overhaul the presentation in many places, but its main purpose is the update to the new C standard, C23. The goal was to publish this new edition of Modern C at the same time as the new C standard goes through the procedure of ISO publication. The closest approximation of the contents of the new standard in a publically available document can be found here. New releases of major compilers already implement most of the new features that it brings.

Among the most noticeable changes and additions that we handle are those for integers: there are new bit-precise types coined _BitInt(N), new C library headers (for arithmetic with overflow check) and (for bit manipulation), possibilities for 128 bit types on modern architectures, and substantial improvements for enumeration types. Other new concepts in C23 include a nullptr constant and its underlying type, syntactic annotation with attributes, more tools for type generic programming such as type inference with auto and typeof, default initialization with {}, even for variable length arrays, and constexpr for named constants of any type. Furthermore, new material has been added, discussing compound expressions and lambdas, so-called “internationalization”, a comprehensive approach for program failure.

Also added has been an appendix and a temporary include header for an easy transition to C23 on existing platforms, that will allow you to start off with C23 right away.

Manning’s early access program (MEAP) for the new edition is still open at

https://www.manning.com/books/modern-c-third-edition

Unfortunately they were not yet able to tell me when their version of the C23 edition will finally be published.

Braiding the spaghetti: implementing defer in the preprocessor

I already talked about a proposal for an extension of the C language called
defer
, that is prospected to either be published in a technical
specification or the next revision, C2Y, of the C standard:

EĿlipsis now implements a simple form of this feature by mixing some specific preprocessor extensions (in particular counters) with the usual macro magic.

Continue reading “Braiding the spaghetti: implementing defer in the preprocessor”

Tail recursion for macros in C

In view of the addition of __VA_OPT__ first to C++ and now to C23, there had been interest in extending the C preprocessor to include recursion. The basic idea would be that __VA_OPT__ can be used as a test within a macro such as in the following

#define AddUp(X, ...) (X __VA_OPT__( + AddUp(__VA_ARGS__)))

Indeed, the __VA_OPT__ clause only inserts its contents if the ... part of the parameter list received at least one argument. So at a first glance you may think that this should be fine, and the above will replace an invocation AddUp(a, b, c) by (a + (b + (c))). There are two reasons why this doesn’t work well.

Continue reading “Tail recursion for macros in C”

EĿlipsis: a language independent preprocessor is released

EĿlipsis is an extension and continuation of the C preprocessor with the
aim to be useful for other technical languages, be they programming
languages or text processing languages.

There were several goals when developing eĿlipsis:

  • Provide a complete specification of a preprocessor that is, as a specification, independent from the C or C++ specifications. This will be provided in a separate document, for which this code here serves as a reference implementation.
  • Properly extend the preprocessor for other languages such that it can take special syntactic properties of these languages into account. Currently we have rudimentary support for lex and for general text processing languages, and more specifically for html and markdown.
  • Develop a project that is fully written in C23 and uses the new features from there extensively.
  • Extend the preprocessor to new features that make programming with it easier. Hopefully at some point it might be integrated into C and C++.
  • Allow the use of modern Unicode to properly specify arithmetic formula and for technology and natural language names.
  • Develop code that uses the new extensions to show their usefulness.
  • Use the new features on the code of eĿlipsis itself (30k loc), to show that these extensions are functioning on a medium size project.
https://gitlab.inria.fr/gustedt/ellipsisthe sources at INRIA’s gitlab server
https://gustedt.gitlabpages.inria.fr/ellipsisdocumentation on the gitlab pages
https://gitlab.inria.fr/gustedt/ellipsis/-/boardsissue trackers on different boards
Bugsif things go wrong
Documentationif you lack an explanation
Feature requestsif you want to do something or get something done
Where to find eĿlipsis

#include __FILE__

Include recursion in C is possible and useful.

Recursive inclusion is possible in C, and more surprisingly it even makes sense in some cases. In fact it provides an easy way to do code unrolling of small code snippets:

#if !defined(DO_I) || (DO_I < DO_BOUND)
# include "do-incr.c"
DO_BODY
# include __FILE__
#endif
#undef DO_I

Continue reading “#include __FILE__”

All chapters of the C23 edition of Modern C now available in early access

At the same time as WG14 (the C committee) voted C23, now all 21 sections of the new edition are available via Manning’s early access program on

Modern C, Third Edition — Covers the C23 standard

This new edition broadly covers all the novelties that will come with C23, many of them make coding in C easier and more reliable. It’s worth a look. Major public domain compilers such as gcc and clang are getting ready to support most of this in their next releases, so you on many platforms you will be able to use these new features right away.

Some pieces are still missing though, namely some of the C library support. Therefor the part in the appendix for C23 about just that is not yet ready, but we will be getting there soon.

You might be interested in the special code that you can get on

Modern C — web page

and the previous post that described the whole

Early access to the C23 edition of Modern C

White space does matter in C23

Usually in C identifiers are not directly followed by strings. But when U prefixed literals were introduced in C. there still were some rare clashes with existing code. This happened were a macro U that expanded to a string was used to add some sort of leading character sequence to a string. Prior, this usage was not sensible to whether or not there was a space between the two. By introducing the prefix the two usages (with and without space) became distinct and code changed its meaning or became invalid. So for this situation, space is in fact already significant.

Generally, it is often assumed that in C spaces don’t contribute much to the interpretation of programming text, but for C23 this has become an over-simplification that does not reflect the situation anymore.

In addition to problems internal to C, there is a problem of interfacing with C++, where some of the rules are different.

syntax meaning, C23 different meaning, C++
# define X(A) function like macro, empty
# define X (A) object macro, expands to (A)
0x4'7'a hex number with digit separators
0x4 '7'a number, character literal, and identifier number, character literal with suffix
0x4 '7' a number, character literal, and identifier
"%" PRIx64 valid format string for printf
"%"PRIx64 valid format string for printf string literal with suffix
R "(hör)" identifier followed by multi-byte string
R"(hör)" identifier followed by multi-byte string raw multi-byte string, contains just hör
R "hör" identifier followed by multi-byte string
R"hör" identifier followed by multi-byte string invalid raw string
U "hör" identifier, followed by multi-byte string
U"hör" UTF-32 string

It would be good if there could be some coordination here between C and C++ about such simple questions concerning lexing and the preprocessor.

Any use of identifiers that are adjacent to character and string literals should be discouraged; I think that such constructs should just be excluded by the syntax. If we want this to be diagnosed it should be before compilation phase 4, in particular before macro expansion. Best would be if this is diagnosed in phase 3, lexing.

Compilers and preprocessor implementations could start to warn about such possible collision immediately, as of today. I don’t see much of a reason to still allow it. Even where there are valid uses, such as for the printf format string macros, the code becomes much easier to read if these are separated from the surrounding format string.

The deprecated attribute in C23 does much more than marking obsolescence

You may already have heard that C23 proposes a new syntax feature called attributes and that one of the standard attributes in C23 is called deprecated. Actually, we got this whole attribute thing and also some of the standard attributes from C++, where they had been introduced in C++11 (I think). One of the uses of this particular attribute is to mark a given feature as obsolescent. For example in C23 we now have

[[deprecated]] char* asctime(const struct tm* timeptr);
[[deprecated]] char* ctime(const time_t* timer);

This simply says that user code should not use these functions anymore, and that compilers should issue a diagnostic if they do.

But this is only one of the possible uses of this new feature. First of all, it can be placed on very different kinds of features, functions, types, variables, enumeration members, structure members …

But most importantly it can be put on features that you somehow have to expose in a header, but which are really only part of the internal dealings of your code, something that users just shouldn’t touch because the feature needs careful maintenance or that simply might change in the future.

In the C23 edition of Modern C, see this post, I just modified a detailed example to use this new feature:

typedef struct circular circular;
struct circular {
  size_t  start [[deprecated("privat")]]; /* First element     */
  size_t  len   [[deprecated("privat")]]; /* Number of elements*/
  size_t  cap   [[deprecated("privat")]]; /* Maximum capacity  */
  double* tab   [[deprecated("privat")]]; /* Data array        */
};

What you see here, is a structure type that can be used by application code: variables can be declared, the size is known. But none of the members of the structure can be accessed directly without being warned.

Continue reading “The deprecated attribute in C23 does much more than marking obsolescence”

Early access to the C23 edition of Modern C

Manning’s early access program (MEAP) for the new edition is now open
at

https://www.manning.com/books/modern-c-third-edition

There is a special code mlgustedt2 to get 45% off of the official price. This is currently limited until Jan 31.

The previous edition already has been largely successful and is considered by some as one of the reference books on C. This new edition has been the occasion to overhaul the presentation in many places, but its main purpose is the update to the new C standard, C23. The goal is to publish this new edition of Modern C at the same time as the new C standard goes through the procedure of ISO publication and as new releases of major compilers will implement all the new features that it brings.

Among the most noticeable changes and additions that we handle are those for integers: there are new bit-precise types coined _BitInt(N), new C library headers (for arithmetic with overflow check) and (for bit manipulation), possibilities for 128 bit types on modern architectures, and substantial improvements for enumeration types. Other new concepts in C23 include a nullptr constant and its underlying type, syntactic annotation with attributes, more tools for type generic programming such as type inference with auto and typeof, default initialization with {}, even for variable length arrays, and constexpr for name constants of any type. Furthermore, new material has been added, discussing compound expressions and lambdas, so-called “internationalization”, a comprehensive approach for program failure.

During MEAP we will also add an appendix and continue work on a temporary include header for an easy transition to C23 on existing platforms, that will allow you to start off with C23 right away.

We also encourage you to post any questions or comments you have about the content in the liveBook Discussion forum. We appreciate knowing where we can make improvements and increase your understanding of the material.

Note that the “about this book” section in MEAP is a bit hidden under the front page. I think that reading this even before going in details is important so I repeat some of this information here.

Continue reading “Early access to the C23 edition of Modern C”
Design a site like this with WordPress.com
Get started