26 Aug, 2015, forrest wrote in the 1st comment:
Votes: 0
I having some issues fixing this error:

handler.c:1267:17: warning: operation on ‘paf->level’ may be undefined [-Wsequence-point]
paf->level = (paf->level += paf_old->level) / 2;

This is the Code:

void affect_join( CHAR_DATA *ch, AFFECT_DATA *paf )
{
AFFECT_DATA *paf_old;
bool found;

found = FALSE;
for ( paf_old = ch->affected; paf_old != NULL; paf_old = paf_old->next )
{
if ( paf_old->type == paf->type )
{
paf->level = (paf->level += paf_old->level) / 2; <— This is the Error
paf->duration += paf_old->duration;
paf->modifier += paf_old->modifier;
affect_remove( ch, paf_old );
break;
}
}

affect_to_char( ch, paf );
return;
}


Also the new messge board, I can't find where you can search for topics, any help there would be helpful as well.
26 Aug, 2015, Davion wrote in the 2nd comment:
Votes: 0
forrest said:
I having some issues fixing this error:

handler.c:1267:17: warning: operation on ‘paf->level’ may be undefined [-Wsequence-point]
paf->level = (paf->level += paf_old->level) / 2;


That line is pretty confusing. I think you probably want

paf->level = (paf->level + paf_old->level) / 2;
27 Aug, 2015, dentin wrote in the 3rd comment:
Votes: 1
This line:

paf->level = (paf->level += paf_old->level) / 2;


is problematic because paf->level is being assigned twice in a single statement. C doesn't allow that.

This is one assignment:

paf->level = …


This is the other assignment:

paf->level += paf_old->level


The C spec doesn't define which one should happen first, and any modern complier worth its salt will kick out a warning or fail if you try to do it.
27 Aug, 2015, quixadhal wrote in the 4th comment:
Votes: 0
dentin said:
This line:

paf->level = (paf->level += paf_old->level) / 2;


is problematic because paf->level is being assigned twice in a single statement. C doesn't allow that.

This is one assignment:

paf->level = …


This is the other assignment:

paf->level += paf_old->level


The C spec doesn't define which one should happen first, and any modern complier worth its salt will kick out a warning or fail if you try to do it.


Slightly misleading. It is a horrible line of code, but it IS defined how it would run by the order of operations of each chunk.

paf->level = (paf->level += paf_old->level) / 2;

Parens have the highest order, so that gets evaluated first.

paf->level += paf_old->level becomes paf->level = paf->level + paf_old->level.

The paren expression has the value of paf->level at that point. Because the expression also had an assignment, that also had to happen at this point.

Division has the next highest precedence, so paren-expression / 2 becomes the new RHS.

Finally, assignment is left, so paf->level gets assigned for the second time.

In this particular case, the first assignment has no real effect other than wasting a few clock cycles… however, if paf->level had been references again further to the right of the assignment, it would have generated a different result than the coder likely expected it to have.
28 Aug, 2015, dentin wrote in the 5th comment:
Votes: 0
quixadhal said:
dentin said:
This line:

paf->level = (paf->level += paf_old->level) / 2;


is problematic because paf->level is being assigned twice in a single statement. C doesn't allow that.

This is one assignment:

paf->level = …


This is the other assignment:

paf->level += paf_old->level


The C spec doesn't define which one should happen first, and any modern complier worth its salt will kick out a warning or fail if you try to do it.


Slightly misleading. It is a horrible line of code, but it IS defined how it would run by the order of operations of each chunk.

paf->level = (paf->level += paf_old->level) / 2;

Parens have the highest order, so that gets evaluated first.

paf->level += paf_old->level becomes paf->level = paf->level + paf_old->level.

The paren expression has the value of paf->level at that point. Because the expression also had an assignment, that also had to happen at this point.

Division has the next highest precedence, so paren-expression / 2 becomes the new RHS.

Finally, assignment is left, so paf->level gets assigned for the second time.

In this particular case, the first assignment has no real effect other than wasting a few clock cycles… however, if paf->level had been references again further to the right of the assignment, it would have generated a different result than the coder likely expected it to have.

No.

While what you've listed above is one possible valid ordering, the C spec does NOT define that order and by default leaves it up to the compiler writer. That warning is there for a reason, and it should not be ignored.
28 Aug, 2015, quixadhal wrote in the 6th comment:
Votes: 0
If the parenthesis weren't there, I would agree with you.

However, while each sub-expression can indeed be computed independently by the compiler, in any order, the parenthesis FORCE the order of assignment to be inside first. There is no way around that. You can't do an assignment until you know the RHS, and you can't know the RHS until all the sub-expressions of it have been completed.

It's still horrible code, and the compiler should spit out a warning about it, but the order is well defined because of the associative rules. Remove the parens, and all bets are off.
29 Aug, 2015, Rhien wrote in the 7th comment:
Votes: 0
What everybody add here is spot on. My question is, what is that line supposed to do (not what is it doing, but what is it supposed to do, e.g. what do you want it to do)? I assume this is what you may want (I'm just guessing, I see that Davion already posted this line)?

paf->level = (paf->level + paf_old->level) / 2;

+= was taken out above… which would be the affect level, plus the old affect level then divided by 2 (level 51 + level 20 = 71 / 2). Is that what you were shooting for? Actually, I just looked at my code base in affect_join and I have the line that I provided so I'm guessing that's what you're looking for. I probably haven't changed it from it's stock value at least I don't recall doing it.
29 Aug, 2015, quixadhal wrote in the 8th comment:
Votes: 0
Rhien said:
What everybody add here is spot on. My question is, what is that line supposed to do (not what is it doing, but what is it supposed to do, e.g. what do you want it to do)? I assume this is what you may want (I'm just guessing, I see that Davion already posted this line)?

paf->level = (paf->level + paf_old->level) / 2;

+= was taken out above… which would be the affect level, plus the old affect level then divided by 2 (level 51 + level 20 = 71 / 2). Is that what you were shooting for? Actually, I just looked at my code base in affect_join and I have the line that I provided so I'm guessing that's what you're looking for. I probably haven't changed it from it's stock value at least I don't recall doing it.


It averages the level of an affect that was cast.

For example, you are level 10 and cast 'piggy smell' on yourself. You now have an affect that's at level 10. A level 30 player wanders by and casts 'piggy smell' on you. The level of the affect now becomes 20. Don't ask me why that's a good idea, but that's what the code likely does. :)
0.0/8