Transitioning libgomp from C to C++ implementation

Christopher Bazley chris.bazley@arm.com
Sat May 9 12:25:35 GMT 2026


Hi Arsen,

On 09/05/2026 10:08, Arsen Arsenović wrote:
> However, C++ enables other things to be done here.  For instance, at
> one of the Office Hours, a mechanism for encoding tree types (without
> requiring rewriting massive amounts of code) was proposed.  It relied on
> templates, and it compiles down to the same code as today, and can
> provide a bridge for existing code.  Essentially, it allowed us to
> specify types such as 'ttree<one_of<PLUS_EXPR, MINUS_EXPR>>' or such,
> and could automatically insert (and elide) gcc_asserts that check for
> those tree codes.
> 
> I don't recall who proposed it or if it ever was sent, but a similar
> thing wouldn't be possible in C.

You could do something like this in C2Y (although it would be more 
straightforward and transparent if the union weren't discriminated):

// https://godbolt.org/z/41xsoWh1a
#include <stdio.h>

typedef struct {
     int dummy;
} tree;

typedef struct {
     tree node;
     int x, y, z;
} plus_expr;

typedef struct {
     tree node;
     double s, t, r;
} minus_expr;

typedef enum {
     TYPE_MINUS_EXPR,
     TYPE_PLUS_EXPR
} node_type;

typedef struct {
     node_type type__;
     union {
         plus_expr *plus;
         minus_expr *minus;
     } u__;
} unary_expr;

#define TO_UNARY_EXPR(E) \
   _Generic(E, \
            plus_expr *: \
             (unary_expr){TYPE_PLUS_EXPR, .u__.plus = (void *)(E)}, \
            minus_expr *: \
             (unary_expr){TYPE_MINUS_EXPR, .u__.minus = (void *)(E)})

#define UNARY_EXPR_TO_PLUS(E) \
   ((E).type__ == TYPE_PLUS_EXPR ? (E).u__.plus : nullptr)

#define UNARY_EXPR_TO_MINUS(E) \
   ((E).type__ == TYPE_MINUS_EXPR ? (E).u__.minus : nullptr)

void foo(unary_expr e)
{
     if (auto p = UNARY_EXPR_TO_PLUS(e))
     {
         printf("%d", p->x);
     }
     else if (auto p = UNARY_EXPR_TO_MINUS(e))
     {
         printf("%g", p->s);
     }
}

void bar(void)
{
     auto plus = &(plus_expr){};
     foo(TO_UNARY_EXPR(plus));

     auto minus = &(minus_expr){};
     foo(TO_UNARY_EXPR(minus));
}

However, I cannot recall any errors in my C programs caused by misuse of 
a discriminated union or a subtype accessed via CONTAINER_OF. Any 
problem worth solving is usually more interesting than that.

-- 
Christopher Bazley
Staff Software Engineer, GNU Tools Team.
Arm Ltd, 110 Fulbourn Road, Cambridge, CB1 9NJ, UK.
http://www.arm.com/


More information about the Gcc mailing list