Getting the number of cases in a switch-case in C

2019-05-26 13:09发布

Is it possible to get the number of cases in a switch case in C without manually adding a counter variable which is incremented in each case?

3条回答
贪生不怕死
2楼-- · 2019-05-26 13:46

This is horrible, but if you are under gcc you can use the COUNTER macro:

#include <stdio.h>

#define ncase (void)__COUNTER__; case

int main(void)
{
    int n = __COUNTER__ + 1;

    switch (1 + 1) {
        ncase 0: break;
        ncase 1: break;
        ncase 2: break;
    }
    n = __COUNTER__ - n;
    printf("%d cases\n", n);
    return 0;
}

Output:

3 cases
查看更多
迷人小祖宗
3楼-- · 2019-05-26 13:48

As I commented earlier, I think you want a dispatch table rather than a switch statement. Here's a little example.

Say you got this:

int find_the_case();
void do_something();
void do_something_different();
void do_something_completly_different();
void do_default();

int main(int argc, char *argv[])
{
    int c = find_the_case();
    switch(c){
        case 0:
           do_something();
           break;
        case 1:
           do_something_different();
           break;
        case 5:
           do_something_completly_different();
           break;
        default:
           do_default();
           break;
    }
    return 0;
}

Now this ca be rewritten to this:

#define MAX_NUMBER_OF_CASES 6
int main_dispatchtable()
{
    void (*table[MAX_NUMBER_OF_CASES])(void)  = {
            [0] = do_something,
            [1] = do_something_different,
            [5] = do_something_completly_different
    };

    int c = find_the_case();
    if( table[c] )
            table[c]();
    else
            do_default();

    /* for the counting */
    int count = 0;
    for (int i = 0; i < MAX_NUMBER_OF_CASES; i++ )
            if( table[i] ) count++;

    return 0;
}

This is usually a much better way than using switch statements. Not only does it make it simpler to add more cases, but it also allows counting of cases. If you have a huge table and sparse cases you can use a hash table instead of a plain array.

EDIT: Of course there are even more advantages with the dispatch table than the switch case, as you can add and remove and change the dispatch table dynamically. That may be the greatest advantage.

查看更多
▲ chillily
4楼-- · 2019-05-26 13:57

(I hope you are on Linux and using a recent GCC compiler)

If you want to count the actual number of cases as seen by the compiler (think of case ranges), you need to know the compiler internal representations, and you could, if compiling with a recent GCC, customize your compiler using GCC MELT and coding our own MELT extension.

BTW, the complexity or efficiency of a switch statement is not only (or mostly) related to the number of cases (since the distribution of cases matters a big lot). See the references here.

Perhaps you might simply use the findgimple mode of GCC MELT to find switch gimple statements which are wide enough.

Maybe you want computed gotos for threaded code...

查看更多
登录 后发表回答