[CF-Devel] Bug in stealing code
crossfire-devel at archives.real-time.com
crossfire-devel at archives.real-time.com
Tue Jun 8 05:48:17 CDT 2004
Mark Wedel wrote:
>
common/item.c: is the get_weight() function really correct? I
>
note that it does not factor in the number of objects. For
>
example, if there are 30 arrows, get_weight returns the weight
>
of just 1 arrow. I'm not sure if that is intentional, but would
>
perhaps seem confusion. I do see it matches the WEIGHT() macro
>
definition in socket/item.c, so maybe so,
It is correct because the client needs both the weight of *one*
item and the number of items. It calculates the total weight of
all items itself.
>
but now I'm curious why make that a function, compared to moving
>
the macro to define.h or the like.
OK, will declare it as a macro in define.h.
The reason for using a function is that I generally tend to avoid
macros: when calling a macro, you have to worry about side effects
(due to possible multiple evaluations of parameters) and also do
not get type-checking by the compiler.
>
server/login.c: I'm not sure if the addition of a
>
esrv_update_item is really necessary, since it immediately
>
follows the esvr_new_player, and weight shouldn't have changed
>
between those two calls.
After checking the source, esrv_new_player indeed sends the
weight. But it does not set the field last_weight. I'll add this
assignment to last_weight, and remove the call to
esrv_update_item.
The reason for adding the call to esrv_update_item was to have
only one place that sets last_weight. But I realized that
esrv_new_player is called two times while creating a new
character, so setting the field last_weight is indeed a good idea.
>
The use of assert doesn't follow with the current coding style,
>
and it's usage is questionable.
>
>
For the few uses, the question is 'if the assert is false, is
>
this a significant error'. If the answer is yes, then having it
>
as an assert may do no good, because the asserts do nothing at
>
all unless NDEBUG is defined, which currently doesn't happen
>
anyplace.
>
>
Thus also means that in normal running code, an error isn't even
>
noted at such asserts. So the usefulness in debugging is pretty
>
limited.
Java exhibits this limited usefulness that you have to explicitly
enable assertions (at runtime). The behavior of C assertions is
exactly the opposite: the C standard says (in section 7.2):
|
If NDEBUG is defined as a macro name at the point in the source
|
file where <assert.h> is included, the assert macro is defined
|
simply as
|
|
#define assert(ignore) ((void)0)
That is, assert() does nothing *only if* NDEBUG ("no debug") is
defined. Otherwise (i.e. if you do not explicitly disable the
assertions by defining NDEBUG), the assertions are active.
>
The current methodoly used in the code is to check those
>
expressions manually (if ... { .. }) and LOG() in all such
>
cases, with the priority of the log message (llevDebug, llWarn,
>
llevError) based on how critical the error is.
This seems right to me for problems that should not happen but may
very well be possible. (I.e. can't read/write a file, a passed
object has wrong type/flags/whatever, etc.)
>
And if it is a critical error, to the extend that trying to
>
continue will just cause it to core dump in the next line or
>
two, might as well call abort right then and there.
These are the types of errors that should be checked with
assert(): to detect an inconsistent internal state that should
never be possible. Therefore assert() prints an error message to
stderr and calls abort() if it fails.
_______________________________________________
crossfire-devel mailing list
crossfire-devel at lists.real-time.com
https://mailman.real-time.com/mailman/listinfo/crossfire-devel
More information about the crossfire
mailing list