glib/docs/toolchain-requirements.md
Emmanuele Bassi 5697c11f1f docs: Update toolchain requirement to C11
We have required C99 for a while; in the meantime, most C toolchains
have moved on to C11 or later as the default C standard.

We still allow for C99 toolchains, but in the future we are going to
require a C11 toolchain to build and use GLib.
2024-06-14 12:35:21 +01:00

6.1 KiB
Raw Blame History

Toolchain/Compiler requirements

GLib strongly recommends a toolchain that supports C11, and requires a toolchain that supports C99.

GLib contains some fall back code that allows supporting toolchains that are not fully C11-compatible.

GLib makes some assumptions about features of the C library and C preprocessor, compiler and linker that may go beyond what C11 mandates. We will use features beyond C11 if they are substantially useful and if they are supported in a wide range of compilers.

In general, we are primarily interested in supporting these four compilers:

  • GCC on *nix
  • Clang (LLVM)
  • MSVC
  • mingw32-w64

This is in keeping with our goal of primarily targetting GNU/Linux, Windows and Mac OS, along with Free Software POSIX-compliant operating systems. See Supported platforms for a bit more information and rationale about that.

In particular, we are interested in MSVC because, although there are other compilers which target Windows, they do not output debugging information that is compatible with MSVC. In interest of usability, we want users of GLib to be able to debug GLib along with their own code while using MSVC as their development environment.

At any given time, GLib may work with mingw32 (from mingw.org) but it is not specifically supported. Politics aside, it seems that mingw.org is mostly dormant and, at this point, all of the big distributions have switched over to mingw32-w64. In several cases, mingw.org has been missing APIs that weve wanted to use and upstream has not been responsive about adding them.

GLib will attempt to remain compatible with other compilers, but some extra features are assumed. Those are detailed below.

GLib additionally requires Python 3 to build.

C99 Varargs macros

Hard requirement.

GLib requires C99 __VA_ARG__ support for both C and C++ compilers.

Symbol visibility control

Not a hard requirement.

When available, GLib uses __attribute__((visibility("hidden"))) and the -fvisibility=hidden compiler option to control symbol visibility, and the -Bsymbolic-functions linker flag.

Builtin atomic operations

Not a hard requirement.

GLib will fall back to using a mutex-based implementation if atomic builtins are not available.

C99 printf and positional parameters

Not a hard requirement.

GLib can be built with an included printf implementation (from GNUlib) if the system printf is deficient.

Constructors and destructors

Hard requirement.

GLib can work with pragma-based, as well as with attribute-based constructor support. There is a fallback for MSVC using a DllMain() instead.

va_list pass-by-reference

Hard requirement.

GLib depends on the ability to pass-by-reference a va_list, as mandated in C99 § 7.15: “It is permitted to create a pointer to a va_list and pass that pointer to another function, in which case the original function may make further use of the original list after the other function returns.”

Support for static inline

Hard requirement.

GLib depends on implementation of the inline keyword as described by C99 § 6.7.4.

GLib further assumes that functions appearing in header files and marked static inline, but not used in a particular compilation unit will:

  • not generate warnings about being unused
  • not be emitted in the compilers output

It is possible that a compiler adheres to C99 § 6.7.4 but not to GLibs further assumptions. Such compilers may produce large numbers of warnings or large executables when compiling GLib or programs based on GLib.

Support for alloca()

Hard requirement.

Your compiler must support alloca(), defined in <alloca.h> (or <malloc.h> on Windows) and it must accept a non-constant argument.

C11 support for type redefinition

Hard requirement.

Your compiler must allow “a typedef name [to] be redefined to denote the same type as it currently does”, as per C11 §6.7, item 3.

Big enums

Hard requirement.

Some of our enum types use 1<<31 as a value. We also use negative values in enums. We rely on the compiler to choose a suitable storage size for the enum that can accommodate this.

Selected C99 features

Hard requirement.

Starting with GLib 2.52 and GTK 3.90, we will be using the following C99 features where appropriate:

  • Compound literals
  • Designated initializers
  • Mixed declarations

Function pointer conversions

Hard requirement.

GLib heavily relies on the ability to convert a function pointer to a void* and back again losslessly. Any platform or compiler which doesnt support this cannot be used to compile GLib or code which uses GLib. This precludes use of the -pedantic GCC flag with GLib.

NULL defined as void pointer, or same size and representation as void pointer

Hard requirement.

GLib assumes that it is safe to pass NULL to a variadic function without explicitly casting it to a char * pointer, e.g.:

g_object_new (G_TYPE_FOO,
              "bar", bar,
              NULL);

This pattern is pervasive throughout GLib and applications that use GLib, but it is also nonportable. If NULL is defined as an integer type, 0, rather than a pointer type, (void *) 0, then using an integer where a pointer is expected results in stack corruption if the size of a pointer is different from the size of NULL. Portable code would use (char *) NULL, (void *) NULL or nullptr (in C23 or C++11 or later) instead.

This requirement technically only applies to C, since GLib is written in C and since C++ does not permit NULL to be defined as a void pointer. If you are writing C++ code that uses GLib, use nullptr to avoid this problem.

GLib further assumes that the representations of pointers of different types are identical, which is not guaranteed.

stdint.h

Hard requirement since GLib 2.67.x.

GLib requires a C99 stdint.h with all the usual sized integer types (int8_t, uint64_t and so on), believed to be supported by all relevant Unix platforms/compilers, as well as Microsoft compilers since MSVC 2013.