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/

Reply via email to