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.
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:
specifically Integral promotion, and even more specifically
the type
bool
can be converted toint
with the valuefalse
becoming0
andtrue
becoming1
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
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP