Thread: Macro Help
View Single Post
Old February 18, 2015, 18:47   #1
chris
PosChengband Maintainer
 
Join Date: Jan 2008
Posts: 702
chris is on a distinguished road
Macro Help

(or, why does GCC keep complaining at me?)

So, I'm trying to do a good thing and look into warnings when compiling poschengband on gcc. I'm not really a C developer, so I don't really know what I am doing!

Anyway, some warnings have me stumped. First, is this:
Code:
cmd1.c:2492:29: warning: comparison is always false due to limited range of data type [-Wtype-limits]
     if (prace_is_(MIMIC_BAT))
The macro prace_is_ is defined as follows:
Code:
#define prace_is_(A) (p_ptr->mimic_form == (A) || (p_ptr->mimic_form == MIMIC_NONE && (A) < MAX_RACES && p_ptr->prace == (A)))
where mimic_form is an s16b and prace is a byte. MIMIC_BAT is indeed outside the range of prace as it is over 1000 so could have been problematic before I added the "(A) < MAX_RACES" check to the macro.

Expanding the macro manually gives a warning as well:
Code:
    if (p_ptr->mimic_form == MIMIC_BAT || (p_ptr->mimic_form == MIMIC_NONE && MIMIC_BAT < MAX_RACES && p_ptr->prace == MIMIC_BAT))
        return 100;
The code works correctly, and as far as I can tell, is coded correctly. There is no chance of comparing prace vs MIMIC_BAT. But even if there was, I don't get the comparison is always false claim. It defintely will return true if mimic_form is set to MIMIC_BAT!

So, is the macro incorrect? I inherited the mixed data sizes from Hengband and would rather not make prace an s16b.

Thanks!

EDIT: I think the warning actually applies only to the p_ptr->prace == (A) comparison, even though that conditional is unreachable in the case A exceeds the storage limits of a byte. Also, gcc is flagging the "if" as the point of the error, rather than the comparison, which is highly confusing. So, for example, changing from a macro to something like:
Code:
bool prace_is_(int which)
{
    if (p_ptr->mimic_form == which)
        return TRUE;
    else if (p_ptr->mimic_form == MIMIC_NONE && p_ptr->prace == which)
            return TRUE;
    return FALSE;
}
fixes the problem.

Last edited by chris; February 18, 2015 at 19:21.
chris is offline   Reply With Quote