View Single Post
Old September 22, 2009, 20:34   #6
Sirridan
Knight
 
Sirridan's Avatar
 
Join Date: May 2009
Posts: 560
Sirridan is on a distinguished road
Quote:
Originally Posted by zaimoni View Post
Which is completely irrelevant to the original bug.

The extent of the ego_resists array is calculated at compile time, and happens to be 12. While in the original code:
Code:
u32b get_new_attr(u32b flags, const u32b attrs[])
{
	size_t i;
	int options = 0;
	u32b flag = 0;
	for (i = 0; i < N_ELEMENTS(attrs); i++)
	{
		/* skip this one if the flag is already present */
		if (flags & attrs[i]) continue;

		/* each time we find a new possible option, we have a 1-in-N chance of
		 * choosing it and an (N-1)-in-N chance of keeping a previous one */
		if (one_in_(++options)) flag = attrs[i];
	}
	return flag;
}
The parameter const u32b attrs[] is decayed at compile time to const u32b *attrs . The language standards (C90/C99/C1X) require 1==N_ELEMENTS(attrs).

The most direct fix is
Code:
u32b get_new_attr(u32b flags, const u32b *attrs, u32b attrs_size)
{
	size_t i;
	int options = 0;
	u32b flag = 0;
	for (i = 0; i < attrs_size; i++)
	{
		/* skip this one if the flag is already present */
		if (flags & attrs[i]) continue;

		/* each time we find a new possible option, we have a 1-in-N chance of
		 * choosing it and an (N-1)-in-N chance of keeping a previous one */
		if (one_in_(++options)) flag = attrs[i];
	}
	return flag;
}
and use N_ELEMENTS on the array where it actually is an array.
Ah forgive my ignorance, makes sense, now I know more of what PowerDiver was saying as well.
Sirridan is offline   Reply With Quote