John Devereux said:
Tim Rentsch said:
[snip]
The expression
'size & -4' may work or it may not, depending on the type of
size. As a reader, I have to wonder about the type of 'size'
in evaluating what it does. The rules of type promotion in
C aren't understood exactly by many developers, and even
those who understand them pretty well can be caught off
guard at times. For example, if we have:
uint32_t size = initializing_expression();
size &= -4;
it's possible that the second line won't do the right thing.
The reason is that, on a platform where 'int' is 64 bits,
the operation is done using 'int' operands rather than
'unsigned int' operands. Granted, the likelihood of getting
unexpected behavior may be small; but still it is possible,
and developers who are careful concern themselves with such
things.
OK, but I wonder does it in fact ever do the wrong thing, even
for the case you mention (i.e. using int operands)? Or any other
integral operands?
Getting a question like this one, especially in comp.lang.c,
it's usually good to give three answers.
Seen in the light of what the standard says, it's certainly
possible that there will be undefined behavior; there are
some grey areas in the standard, but this isn't one of them.
That settles the issue as far as comp.lang.c is concerned.
At the other end of the spectrum, practically speaking,
most developers simply won't encounter an implementation
where 'size &= -4;' misbehaves. If you had to bet, unless
there is some reason to believe that something about the
situation is unusual, the right bet is that 'size &= -4;'
will behave as desired.
In between, my guess is there are some implementations --
even if you and I are unlikely to encounter them -- where
'size &= -4;' doesn't do what you want (for some values of
signed integer types). Because I don't know and because I
think it's likely that such implmentations are out there
_somewhere_, I think it's wise to steer clear of potential
undefined behavior. This question is one where it's very
hard to be sure. So, it seems better to choose the safer
path.
Furthermore it's good to develop the habit. Even if this
particular case never causes you a problem, having the habit
of writing code that is safe across widely different
implementations will probably spare you some later grief.