0

During the greedy problem in pset1 I wrote this function:

void greedy(int coin_type, int *change, int *coins) {
    while (*change / coin_type > 0) {
        *coins++;
        *change -= coin_type;
    }
}

but when compiling I'd receive the error:

gabriel_greedy.c:32:9: error: expression result unused
  [-Werror,-Wunused-value]
    *coins++;
    ^~~~~~~~

So when I asked a fellow student what constitutes 'using' a variable, they told me that 'having it as part of a condition test in the function body qualifies as using that variable'.

I then went ahead and added this nonsensical but theoretically valid condition test:

void greedy(int coin_type, int *change, int *coins) {
    while (*change / coin_type > 0 && *coins != -1) {
        *coins++;
        *change -= coin_type;
    }
}

But still I received the same error:

gabriel_greedy.c:32:9: error: expression result unused
  [-Werror,-Wunused-value]
    *coins++;
    ^~~~~~~~

However, when I instead did:

void greedy(int coin_type, int *change, int *coins) {
    while (*change / coin_type > 0) {
        *coins += 1;
        *change -= coin_type;
        if (*coins != -1) {
            continue;
        }

the program compiled successfully. Now can someone please explain to me:

  1. What constitutes 'using' a variable in a function, and why does the compiler complain in the first case, second case but not in the last case?
  2. How is the third version of the function qualitatively different from the second version as it relates to 'using' the variable *coins, and compiling successfully or not?

1 Answer 1

1

The root of this problem lies in the order of operations. In C, postfix increment (++) binds more tightly than dereference (*). Thus, what the code *coins++; does is not to dereference coins and then increment the stored value; rather, it increments the pointer coins and then dereferences this new pointer. The compiler is complaining of the fact that the resulting int value isn't used for anything.

The reason it works in the last example is that you switch out the postfix increment for a compound assignment operator (+=), which has a much lower precedence.

3
  • So this is entirely independent of whether or not *coins is part of a condition test, and 'using a variable' does not necessitate this? Commented Feb 7, 2017 at 18:44
  • Right. The issue here isn't that the variable is unused. It's that the expression result (i.e., the value obtained by dereferencing the pointer) isn't used for anything: it's computed but then immediately forgotten.
    – Levi Roth
    Commented Feb 7, 2017 at 18:48
  • It's possible that the person you talked to was confusing the "Unused variable" warning, which does exist but isn't relevant here, with the "expression result unused" warning.
    – Levi Roth
    Commented Feb 7, 2017 at 18:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .