Path: csiph.com!eternal-september.org!feeder.eternal-september.org!nntp.eternal-september.org!.POSTED!not-for-mail
From: Tim Rentsch
Newsgroups: comp.lang.c
Subject: Re: Alternatives to C (was Re: Safety of casting from 'long' to 'int')
Date: Thu, 14 May 2026 10:53:32 -0700
Organization: A noiseless patient Spider
Lines: 76
Message-ID: <864ik9j2sj.fsf@linuxsc.com>
References: <10su8cn$am9i$1@dont-email.me> <10u0k0k$1l93l$30@dont-email.me> <10u23g1$ev2$5@reader1.panix.com> <10u2jpk$2t96p$6@kst.eternal-september.org> <10u2mb2$8uu$1@reader1.panix.com> <10u2uu9$31igh$1@kst.eternal-september.org>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Injection-Date: Thu, 14 May 2026 17:53:33 +0000 (UTC)
Injection-Info: dont-email.me; logging-data="579090"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19ZbWAkh+rmkfddi6iYVKcS9wycfpRBScM="; posting-host="d527bc7f7e7e084b0e2324cbe71ceb59"
User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
Cancel-Lock: sha1:E4yVKz52p/zjjJzK7BscLULGtlQ= sha1:myHPsT+W2qMnORcUU4IumNo2cxI= sha256:rZeBIxH15Sx1ej7ZkOdDcMA5pVJm4TIUF0hc6fDyr5Y= sha1:Zcf+GxniMKE8r8DmqD8ryHNxu9Q=
Xref: csiph.com comp.lang.c:398961
Keith Thompson writes:
> [...] the issue being discussed was that multiple cases (that may
> not be contiguous) depend on the default fallthrough behavior.
>
> case 10:
> case 20:
> case 30:
> whatever();
> break;
>
> In a hypothetical C-like language without default fallthrough, it
> would make sense to invent a different syntax. For C repeating the
> "case" keyword is slightly ugly, but probably not worth fixing.
Both gcc and clang, with options -std=c99 -pedantic -Wall -Wextra,
accept the code below and give no diagnostics:
#include
#include "cases.h"
int
main( int argc, char *argv[] ){
switch( argc-1 ){
cases( 2, 3, 5, 8 ):
printf( " okay - we got %d arguments\n", argc-1 );
printf( " argv[%d] is %s\n", argc-1, argv[argc-1] );
break;
cases( 0, 1, 4, 6, 7, 9 ):
printf( " oops - there were %d arguments\n", argc-1 );
break;
case 10:
printf( " 10 -" );
FALLTHROUGH;
default:
printf( " golly... there were %d arguments\n", argc-1 );
}
printf( "\n" );
return 0;
}
The cases() macro is a fairly straightforward application of variadic
macros, as follows:
#define ARGS_N_(...) \
ARGS_N_X_( __VA_ARGS__, \
09, 08, 07, 06, 05, 04, 03, 02, 01, 00 \
)
#define ARGS_N_X_( dummy, _9, _8, _7, _6, _5, _4, _3, _2, _1, ... ) _1
#define cases(...) casesx_( ARGS_N_( __VA_ARGS__ ), __VA_ARGS__ )
#define casesx_( N, ... ) casesy_( N, __VA_ARGS__ )
#define casesy_( N, ... ) cases_ ## N ## _( __VA_ARGS__ )
#define cases_01_(a) case a
#define cases_02_(a,...) case a : cases_01_( __VA_ARGS__ )
#define cases_03_(a,...) case a : cases_02_( __VA_ARGS__ )
#define cases_04_(a,...) case a : cases_03_( __VA_ARGS__ )
#define cases_05_(a,...) case a : cases_04_( __VA_ARGS__ )
#define cases_06_(a,...) case a : cases_05_( __VA_ARGS__ )
#define cases_07_(a,...) case a : cases_06_( __VA_ARGS__ )
#define cases_08_(a,...) case a : cases_07_( __VA_ARGS__ )
#define cases_09_(a,...) case a : cases_08_( __VA_ARGS__ )
It's easy to see how to extend this definition to allow more cases, if
that is needed.
Personally I would rather have something that works in C99, etc, now,
than to wait for some possible change at some point in the indefinite
future.