c pointer manipulation in switch statement

c pointer manipulation in switch statement  using -'c,operator-precedence,post-increment'

Hi folks i tried to program a simple switch statement and stuck uppon this problem.
I cant figure out why this code works correctly, i guess it is because the precedence of the operators ** and ++.
If this is the case ill be happy if someone can write an example how should i use value-at * and inc/dec operator in a statement like below.

Thanks in advance,

while (--argc > 0)
        switch (**argv)

and this code dont

while (--argc > 0)
        switch (**(argv++))

Full code:

while (--argc > 0) {
        switch (**(argv++)) {
        case '\0':
            panic("empty command line argument");
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            push (atof(*argv));
        case '+':
            push(pop() + pop());
        case '-':
            op2 = pop();
            push(pop() - op2);
        case '*':
            push(pop() * pop());
        case '/':
            op2 = pop();
            push(pop() / op2);
            panic("unknown command");


asked Sep 9, 2015 by TerMonteneg
0 votes

2 Answers

0 votes

Using the postincrement on a given variable in any expression causes the variable to increment after the expression has been evaluated.

As stated by your first, working code, where you increment argv value before getting it's referenced value in the switch, you want the variable to be incremented before your expression is evaluated, so you need to use the preincrement:

while (--argc > 0) 
        switch (**(++argv)) 
answered Sep 9, 2015 by LukXLF
0 votes

I think you are being confused by the parentheses. Parentheses affect the order of evaluation, but you are using post increment, which is applied at the end, no matter what order the operators are evaluated.

In your first snippet the order is clear: first you increase argv, then you dereference it. That is, you dereference the "next" element, not the current one.

In your second snippet you want to achieve the same result, and you are playing with parentheses. This is not the solution. Parentheses affect the order in which the 2 operators (++ and **) are evaluated, but this doesn't mean the effects are applied in that order.

For example: if you wrote

switch ((**argv)++)

the compiler would apply ** first, dereferencing it, giving you the content, and then it would apply ++ on it (obviously argv must be a data type which can be increased or there will be an error, but it doesn't matter here). Instead, if you write, as you did,

switch (**(argv++))

the increment (++) is applied first, and then the indirection (**). But here is the trick: post increment is still post increment. Applying the post increment here means: take the current value, and when everything is finished remember to increase it. So argv is used as it is, without increasing it (yet), and sent to **, which will give the current value (not the next one!). Then, after switch has read the current element, argv is increased (post-increment), so that if your cases printed **argv you would notice it's the "next" value.

A solution is using pre-increment:

switch (**(++argv))

but if you ask me, the real solution is to avoid these headaches entirely and write the code in 2 separate lines, so that it's immediately obvious what happens. As you did in your first snippet. This is the most readable style, and therefore should be the preferred choice. Then you can forget about everything: order of evaluation, parentheses, pre- vs post-increment, associativity.

answered Sep 9, 2015 by DeaBromilow