Constant memory table doesn't reduce to int in switch statement,why?

Discussion in 'C Programming' started by Remco Poelstra, Jun 30, 2003.

  1. Hi,

    I've the following piece of code:

    enum {
    PLAY,
    STOP,
    PAUSE
    };

    struct command {
    unsigned char bytecode;
    unsigned char arguments;
    char *name;
    };

    struct command slink_commands[] = {
    {0x00,0,"Play"},
    {0x01,0,"Stop"},
    {0x02,0,"Pause"},
    };


    int main(void) {

    switch(1) {
    case slink_commands[PLAY].bytecode:
    break;
    }
    return 0;
    }


    My compiler now gives the warning that the case label doesn't reduce to
    an integer constant. Why? The value is known at compile time...
    Is this construction impossible, or can I tell my compiler some way that
    it IS a constant?

    (I'm using GCC 3.3.1, but I think it's more a C problem, than a GCC
    problem, so I ask here. Sorry if this is the wrong place....)


    Thanks in advance,

    Remco Poelstra
    Remco Poelstra, Jun 30, 2003
    #1
    1. Advertising

  2. Re: Constant memory table doesn't reduce to int in switch statement, why?

    Remco Poelstra <> wrote (30 Jun 2003) in
    news:bdq6tf$scm$1.nb.home.nl / comp.lang.c:

    > Hi,
    >
    > I've the following piece of code:
    >
    > enum {
    > PLAY,
    > STOP,
    > PAUSE
    > };
    >
    > struct command {
    > unsigned char bytecode;
    > unsigned char arguments;
    > char *name;
    > };
    >
    > struct command slink_commands[] = {
    > {0x00,0,"Play"},
    > {0x01,0,"Stop"},
    > {0x02,0,"Pause"},
    > };
    >
    >
    > int main(void) {
    >
    > switch(1) {
    > case slink_commands[PLAY].bytecode:
    > break;
    > }
    > return 0;
    > }
    >
    >
    > My compiler now gives the warning that the case label doesn't reduce
    > to an integer constant. Why?


    Because it's a variable.

    > The value is known at compile time...


    Its initial value is known. It is still a variable.

    > Is this construction impossible, or can I tell my compiler some way
    > that it IS a constant?


    You have a lookup table defined, so look up the value. "switch" is not
    supposed to be the answer to every problem.

    >
    > (I'm using GCC 3.3.1, but I think it's more a C problem, than a GCC
    > problem, so I ask here.


    You're right. Your code is invalid C, no matter what gcc or some other
    compiler might do with it.



    --
    Martin Ambuhl
    Returning soon to the
    Fourth Largest City in America
    Martin Ambuhl, Jun 30, 2003
    #2
    1. Advertising

  3. Re: Constant memory table doesn't reduce to int in switch statement, why?

    In 'comp.lang.c', Remco Poelstra <> wrote:

    > Hi,
    >
    > I've the following piece of code:
    >
    > enum {
    > PLAY,
    > STOP,
    > PAUSE
    > };
    >
    > struct command {
    > unsigned char bytecode;
    > unsigned char arguments;
    > char *name;
    > };
    >
    > struct command slink_commands[] = {
    > {0x00,0,"Play"},
    > {0x01,0,"Stop"},
    > {0x02,0,"Pause"},
    > };


    Why not

    struct command slink_commands[] = {
    {PLAY,0,"Play"},
    {STOP,0,"Stop"},
    {PAUSE,0,"Pause"},
    };

    ? Sounds more consistent and maintainable, isn't it?

    > int main(void) {
    >
    > switch(1) {
    > case slink_commands[PLAY].bytecode:


    A twisted and wrong way of writing:

    case PLAY:

    > break;
    > }
    > return 0;
    > }
    >
    >
    > My compiler now gives the warning that the case label doesn't reduce to
    > an integer constant. Why? The value is known at compile time...


    It's true. 'slink_commands[PLAY].bytecode' is far to be a 'constant
    integer expression', because 'slink_commands' is an initialized variable.
    Even with 'const', it will still be a (read-only) variable.

    Constant integer expressions are made of integers, enums, integer macros and
    arithmetic or bitwise operators.

    --
    -ed- [remove YOURBRA before answering me]
    The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    <blank line>
    FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
    Emmanuel Delahaye, Jul 1, 2003
    #3
  4. Remco Poelstra

    Daniel Haude Guest

    Re: Constant memory table doesn't reduce to int in switch statement, why?

    On Mon, 30 Jun 2003 22:40:21 +0200,
    Remco Poelstra <> wrote
    in Msg. <bdq6tf$scm$1.nb.home.nl>

    > I've the following piece of code:
    >
    > enum {
    > PLAY,
    > STOP,
    > PAUSE
    > };
    >
    > struct command {
    > unsigned char bytecode;
    > unsigned char arguments;
    > char *name;
    > };
    >
    > struct command slink_commands[] = {
    > {0x00,0,"Play"},
    > {0x01,0,"Stop"},
    > {0x02,0,"Pause"},
    > };
    >
    >
    > int main(void) {
    >
    > switch(1) {
    > case slink_commands[PLAY].bytecode:
    > break;
    > }
    > return 0;
    > }


    Others already have pointed out why this doesn't work in C. But I think
    this is not even what you'd /want/ to write, even if it did work. Actually
    the whole point of constructing lookup tables (usually in connection with
    function pointers) is to avoid switch statements. But anyway, here's what
    you probably wanted to write (having added an element MAX_COMMANDS to
    your enum):

    /* UNTESTED CODE JUST TYPED IN NEWSREADER */

    int main(void)
    {
    int i;
    int code;

    code = get_bytecode_from_somewhere();
    for (i = 0; i < MAX_COMMANDS; i++) {
    if (code == slink_commands.bytecode) {
    break;
    }
    }
    switch (i) {
    case PLAY : /* play */ break;
    case STOP : /* ... etc... */ break;
    /* ... */
    case MAX_COMMANDS : /* invalid bytecode */ break;
    default : /* IMPOSSIBLE */
    }
    }

    Obviously performance-wise it doesn't make too much sense to first have a
    loop iteratig over several possible bytecodes to find the lookuop table
    index, and then switching on that index. But it's pretty much all you can
    do with your table at the moment.

    --Daniel

    --
    "With me is nothing wrong! And with you?" (from r.a.m.p)
    Daniel Haude, Jul 1, 2003
    #4
  5. Thanks for all the replies.

    I thought that such a table would be nice with a switch statement, but I
    'll follow your common advice and try it without the switch statement
    (using function pointers).
    It wil at least save me some line or 45 to construct the switch.

    Thanks again,

    Remco Poelstra
    Remco Poelstra, Jul 1, 2003
    #5
  6. Groovy hepcat Remco Poelstra was jivin' on Mon, 30 Jun 2003 22:40:21
    +0200 in comp.lang.c.
    Constant memory table doesn't reduce to int in switch statement,
    why?'s a cool scene! Dig it!

    > switch(1) {

    ^
    Another point, which noone else mentioned: you have a constant
    expression for the value being tested. An integer literal, such as the
    above 1, is a constant expression. This makes no sense. The idea
    behind a switch statement is that it tests the value of an expression
    that may have either of several values (to determine which of those
    several values it has). Obviously a constant expression can only have
    one value, so testing it in such a way is pointless.

    --

    Dig the even newer still, yet more improved, sig!

    http://alphalink.com.au/~phaywood/
    "Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
    I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
    Peter Shaggy Haywood, Jul 4, 2003
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    36
    Views:
    1,471
    Chris Uppal
    Jun 6, 2005
  2. Schnoffos
    Replies:
    2
    Views:
    1,206
    Martien Verbruggen
    Jun 27, 2003
  3. pete
    Replies:
    2
    Views:
    1,466
  4. Hal Styli
    Replies:
    14
    Views:
    1,625
    Old Wolf
    Jan 20, 2004
  5. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,804
    Smokey Grindel
    Dec 2, 2006
Loading...

Share This Page