Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
817 views
in Technique[技术] by (71.8m points)

c - Does x ^= x & -x; where x is an unsigned integer invoke UB?

Does this function invoke undefined behavior due to the - operator being applied to x which is unsigned? I searched the standard and couldn't find an explanation.

unsigned foo(unsigned x)
{
    return x ^= x & -x;
}

IMO yes.

edit
void func(unsigned x) 
{
    printf("%x", -x);
}

int main(void)
{
    func(INT_MIN);
}

IMO The only explanation is that it was promoted to larger signed integer size then converted to unsigned.

If it is promoted to larger integer size, what will happen if there is no larger signed integer type?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The behavior of this expression is well defined.

Constructs similar to x = x + 1 are allowed because x isn't assigned a value until all other subexpressions are evaulated. The same applies in this case.

There is also no problem with -x because the expression has unsigned type and thus has well defined wraparound behavior as opposed to overflowing.

Section 6.5.3.3p3 of the C standard regarding the unary - operator states:

The result of the unary - operator is the negative of its (promoted) operand. The integer promotions are performed on the operand, and the result has the promoted type.

So since no promotion occurs the type remains unsigned throughout the expression. Though not explicitly stated in the standard, -x is effectively the same as 0 - x.

For the specific case of INT_MIN being passed to this function, it has type int and is outside of the range of unsigned, so it is converted when passed to the function. This results in the signed value -2,147,483,648 being converted to the unsigned value 2,147,483,648 (which in two's complement happen to have the same representation, i.e. 0x80000000). Then when -x is evaluated, it wraps around resulting in 2,147,483,648.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...