TransWikia.com

C recursion return values

Stack Overflow Asked by johnsulaw on December 3, 2020

I am trying to return a value from recursive function, but somehow keep getting the wrong value.

The function where im getting the wrong return value looks like this:

int statement_list(ParserData *data){

    int result = ERR_SYN;

    if(data->token.type == tt_right_bra)
    {
        if((result = load_token(data)) != 0) return result;

        return 0;
    }else if(data->token.type == tt_keyword_if    ||
            data->token.type == tt_eol            ||
            data->token.type == tt_id             ||
            data->token.type == tt_keyword_for    ||
           data->token.type == tt_keyword_return)
   {
       if((result = statement(data) != 0 )) return result;
       if((result = statement_list(data) != 0 )) return result; 

       return 0;
   }

   return result;

The program goes as expected, then enters function statement(), where it executes the following block:

else if (data->token.type == tt_left_par){
        if(check_if_id_declared(symtable, data->prev_token.attribute.value) != 1){
            result = ERR_SEM_BAD_DEFINITION;
            return result;
        }
}

Both if conditions are true (which is expected), variable result is set to 3 (macro is defined as 3) as it should be and the program returns to function statement_list with this value. In statement_list I now expect result = 3, however I keep gettin result = 1 after the program returns.

I have no idea why it does that, thanks for any suggestions.

One Answer

You have an operator precedence bug, because you were sloppy with your parentheses.

if((result = load_token(data)) != 0) return result;

is correct: the (result = load_token(data)) expression is compared to zero.

if((result = statement(data) != 0 )) return result;

is wrong: the outer parentheses do nothing, and in result = statement(data) != 0, the != operator has higher precedence than the assignment operator =. So this expression is evaluated as

result = (statement(data) != 0)

So, when statement returns 3, the expression statement(data) != 0 is true, and result is set to the boolean true promoted to an integer, which is 1.

Reference:

  • operator precedence

  • implicit conversion

    specifically Integral promotion, and even more specifically

    the type bool can be converted to int with the value false becoming ​0​ and true becoming 1


If you're actually writing C++ (as originally tagged), you can use strongly-typed enumerations for your return codes, and then you can't accidentally promote from bool like this.

If you're actually writing C (as currently tagged) - my links above are for the C++ docs, but C behaves the same way in this context. You don't have strongly-typed enumerations though, so you just need to be more careful.

Correct answer by Useless on December 3, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP