plan9-extensions ¶Posted on Tue Jan 10, 2017
I have been compiling code with the gnu C
language compiler (gcc) since I started using gnu+Linux back in 1997
(more or less). But I very rarely read its documentation, especially the C language
extensions that it implements.
Lately, while learning a bit about support for the
C11 standard, I have
discovered that gcc implements unnamed fields in structures, with some
extensions, through the -fplan9-extensions option. I find these amazing.
From a certain point of view, these extensions are just the default offered by the
C++ language; but under the C language they are amazing.
Here is an example:
/* demo.c --
*
* Compile this with:
*
* $ gcc -std=c11 -Wall -fplan9-extensions -o demo demo.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int one;
} alpha_t;
typedef struct {
alpha_t;
int two;
} beta_t;
void
print_alpha (alpha_t * self)
{
fprintf(stderr, "alpha: %d\n", self->one);
}
void
print_beta (beta_t * self)
{
fprintf(stderr, "beta: %d %d\n", self->one, self->two);
}
int
main (int argc, const char *const argv[])
{
beta_t B = { .one = 1, .two = 2 };
print_alpha(&B);
print_beta (&B);
exit(EXIT_SUCCESS);
}
/* end of file */
we see that the definition of beta_t contains an unnamed field of type
alpha_t:
typedef struct {
alpha_t;
int two;
} beta_t;
and we can access its fields, nested in an instance of beta_t, transparently
both in the initialiser:
beta_t B = { .one = 1, .two = 2 };
and from a pointer to beta_t in the function print_beta():
fprintf(stderr, "beta: %d %d\n", self->one, self->two);
Also, when a pointer to beta_t is used as operand for a function expecting a
pointer to alpha_t as argument: the pointer conversion is performed
automatically by the compiler, without the need to cast it explicitly. So we can
simply write:
print_alpha(&B);
rather than:
print_alpha((alpha_t *)&B);
I have decided to try these features in my recent CCExceptions project.