Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Hurray for constant expressions!

51 views
Skip to first unread message

luser droog

unread,
Jun 2, 2014, 2:01:22 AM6/2/14
to
Trying to simplify some nested switch statements
over enum values. Expressions saves the day.

#include<stdio.h>

enum { X=1, Y=2 };

int pair(int a, int b){
return a*(Y+1)+b;
}

int switchpair(int p){
switch(p){
case 0:
printf("0\n"); break;
case Y:
printf("Y\n"); break;
case X*(Y+1):
printf("X\n"); break;
case X*(Y+1)+Y:
printf("XY\n"); break;
}
return 0;
}

int main(){

int x;
x = pair(X,Y);
switchpair(x);
x = pair(0,Y);
switchpair(x);
x = pair(X,0);
switchpair(x);
x = pair(0,0);
switchpair(x);

return 0;
}



Output:

XY
Y
X
0

--
a flattened nest. so very very sad.

Richard Bos

unread,
Jun 2, 2014, 10:23:23 AM6/2/14
to
luser droog <luser...@gmail.com> wrote:

> Trying to simplify some nested switch statements
> over enum values. Expressions saves the day.
>
> enum { X=1, Y=2 };
>
> int pair(int a, int b){
> return a*(Y+1)+b;
> }
>
> int switchpair(int p){
> switch(p){
> case 0:
> printf("0\n"); break;
> case Y:
> printf("Y\n"); break;
> case X*(Y+1):
> printf("X\n"); break;
> case X*(Y+1)+Y:
> printf("XY\n"); break;
> }
> return 0;
> }

It works, but it's a maintenance nightmare. At the very least add a
SWITCHHACKMAX value, in case you want to later add Z and X2 (and then,
three years later, Y2017, and...), and write a*(SWITCHHACKMAX+1)+b
instead of relying on Y always being the largest value. Also, change
pair() to a macro, so you can use it in switchpair() as well - self-
documenting code is always better - like this:

enum { X=1, Y=2, SWITCHHACKMAX };
/* Use a shorter name for SWITCHHACKMAX if you must, but it only
appears in these two lines, so why would you? */

#define PAIR(a, b) (a)*(SWITCHHACKMAX+1)+(b);

int switchpair(int p){
switch(p){
case PAIR(0,0):
printf("0\n"); break;
case PAIR(0,Y):
printf("Y\n"); break;
case PAIR(X,0):
printf("X\n"); break;
case PAIR(X,Y):
printf("XY\n"); break;
}
return 0;
}

And, whatever you do - comment this! It's hack code, it requires
commenting.

Richard

luser droog

unread,
Jun 3, 2014, 1:48:56 PM6/3/14
to
On Monday, June 2, 2014 9:23:23 AM UTC-5, Richard Bos wrote:
> luser droog <luser...@gmail.com> wrote:
>
>
> > Trying to simplify some nested switch statements
> > over enum values. Expressions saves the day.
> >
<snip>
>
> It works, but it's a maintenance nightmare. At the very least add a
> SWITCHHACKMAX value, in case you want to later add Z and X2 (and then,
> three years later, Y2017, and...), and write a*(SWITCHHACKMAX+1)+b
> instead of relying on Y always being the largest value. Also, change
> pair() to a macro, so you can use it in switchpair() as well - self-
> documenting code is always better - like this:
>
> enum { X=1, Y=2, SWITCHHACKMAX };
> /* Use a shorter name for SWITCHHACKMAX if you must, but it only
> appears in these two lines, so why would you? */
>
> #define PAIR(a, b) (a)*(SWITCHHACKMAX+1)+(b);
>
> int switchpair(int p){
> switch(p){
> case PAIR(0,0):
> printf("0\n"); break;
> case PAIR(0,Y):
> printf("Y\n"); break;
> case PAIR(X,0):
> printf("X\n"); break;
> case PAIR(X,Y):
> printf("XY\n"); break;
> }
> return 0;
> }
>
> And, whatever you do - comment this! It's hack code, it requires
> commenting.
>

Yes, the macro is better for this.
The application is *all* hack-code, but I did hazard a single comment
in accordance with your suggestion. This extract shows some of the
context where I'm using this hack.

from https://github.com/luser-dr00g/inca/blob/master/inca2.c

#define CASE break;case
enum types { NUL, CHR, INT, DBL, BOX, FUN, NTYPES };
//TPAIR() combines types into a single value that can be switch()ed
#define TPAIR(a,b) ((a)*NTYPES+(b))

#define V2(f) ARC f(ARC a,ARC w)
#define DO(n,x) {I i=0,_n=(n);for(;i<_n;++i){x;}}

#define MATHOP2(op) \
I r=AR(w),*d=AD(w),n=AN(w);ARC z; \
switch(TPAIR(AT(a),AT(w))) { \
CASE TPAIR(INT,INT): \
z=ga(INT,r,d); DO(n,AV(z)[i]=AV(a)[i] op AV(w)[i]); \
CASE TPAIR(INT,DBL): \
z=ga(DBL,r,d); DO(n,((D*)AV(z))[i]=AV(a)[i] op ((D*)AV(w))[i]); \
CASE TPAIR(DBL,INT): \
z=ga(DBL,r,d); DO(n,((D*)AV(z))[i]=((D*)AV(a))[i] op AV(w)[i]); \
CASE TPAIR(DBL,DBL): \
z=ga(DBL,r,d); DO(n,((D*)AV(z))[i]=((D*)AV(a))[i] op ((D*)AV(w))[i]); \
} R z;

V2(plus){ MATHOP2(+) }
0 new messages