Mar 23, 2012

[c][c++][NOTE] Clifford's Device

A very interesting discussion.

C compiler thinks different than us(in Chinese)

Clifford's Device


#include <stdio.h>
#define DEBUG 1
#define DBG( ... ) \
    if (DEBUG) {  __VA_ARGS__; }
int main(int argc, char *argv[]) {
    char *num;
    switch (argc - 1) {
             case  0: num =  "zero";
        DBG( case  1: num =   "one"; )
        DBG( case  2: num =   "two"; )
        DBG( case  3: num = "three"; )
        DBG( default: num =  "many"; )
        while (--argc)
            printf("%s ", argv[argc]);
        printf("\nArgument count: %s\n", num);
        break;
    }
    return 0;
}
//-----------
#include 

int main(int argc, char **argv)
{
        int num;

        if (argc != 3) {
                fprintf(stderr, "Usage: %s {BIN|OCT|DEC|HEX|STR} {ARG}\n", argv[0]);
                return 1;
        }

        if (!strcmp(argv[1], "BIN")) {
                num = strtol(argv[2], NULL, 2);
                goto number_mode;
        } else
        if (!strcmp(argv[1], "OCT")) {
                num = strtol(argv[2], NULL, 8);
                goto number_mode;
        } else
        if (!strcmp(argv[1], "DEC")) {
                num = strtol(argv[2], NULL, 10);
                goto number_mode;
        } else
        if (!strcmp(argv[1], "HEX")) {
                num = strtol(argv[2], NULL, 16);
                goto number_mode;
        } else
        if (!strcmp(argv[1], "STR")) {
                printf("Called with string argument: '%s'\n", argv[2]);
        } else {
                printf("Called unsupported mode: '%s'\n", argv[1]);
        }

        /* Clifford's Device */
        if (0) {
number_mode:
                printf("Called with numeric argument: %d\n", num);
        }

        return 0;
}

//----------
#include 

int main(int argc)
{
        char *num;

        switch (argc-1)
        {
        if (0) { case  0: num = "zero";  }
        if (0) { case  2: num = "two";   }
        if (0) { case  3: num = "three"; }
        if (0) { case  4: num = "four";  }
        if (0) { case  5: num = "five";  }
        if (0) { default: num = "many";  }
                printf("Called with %s arguments.\n", num);
                break;
        case 1:
                printf("Called with one argument.\n");
        }

        return 0;
}

As we should notice how switch is implemented in the compiler.
It's actually "goto". Reference: Duff's_device

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.