Hurray for constant expressions!

Discussion in 'C Programming' started by luser droog, Jun 2, 2014.

  1. luser droog

    luser droog Guest

    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
     
    luser droog, Jun 2, 2014
    #1
    1. Advertisements

  2. luser droog

    Richard Bos Guest

    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
     
    Richard Bos, Jun 2, 2014
    #2
    1. Advertisements

  3. luser droog

    luser droog Guest

    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)=AV(a) op AV(w)); \
    CASE TPAIR(INT,DBL): \
    z=ga(DBL,r,d); DO(n,((D*)AV(z))=AV(a) op ((D*)AV(w))); \
    CASE TPAIR(DBL,INT): \
    z=ga(DBL,r,d); DO(n,((D*)AV(z))=((D*)AV(a)) op AV(w)); \
    CASE TPAIR(DBL,DBL): \
    z=ga(DBL,r,d); DO(n,((D*)AV(z))=((D*)AV(a)) op ((D*)AV(w))); \
    } R z;

    V2(plus){ MATHOP2(+) }
     
    luser droog, Jun 3, 2014
    #3
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.