~0 undefined? [英] ~0 undefined?

查看:68
本文介绍了~0 undefined?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

~0会产生未定义的行为吗? C ++ 03第5节第5段似乎

建议如此:


如果在评估表达式时,结果不是

在数学上定义或不在可表示的值范围内

的类型,行为未定义[...]



一元的描述〜(C ++ 03第5.3.1节第8段):


的操作数?应具有整数或枚举类型;

结果是其操作数的补码。整体促销

。结果的类型是提升的

操作数的类型。 [...]



但也许是一个的补充表示类型将具有所有位反转的值,而不是反转二进制表示中所有

位的数学结果。例如,在32位
int的机器上,0的一个补码(尝试)的值是2 ^ 31-1,这是

不能用signed int表示,因此是未定义的,或者它是什么?
具有所有设置位所具有的带符号int的值(-1

在两个补码机上?


为简单起见,我使用了~0的情况;在实践中,这个问题可能会发生

当使用掩码的补码进行AND运算时,例如n& = ~0x0F清除

n的低4位,或者〜 n& 0x0F找到n的反相低4位。

解决方案

blargg写道:


是否~0会产生未定义的行为? C ++ 03第5节第5段似乎

建议如此:


>如果在评估表达式时,结果是不是数学定义或不在可表示值范围内
对于其类型,行为未定义[...]



描述一元〜(C ++ 03第5.3.1节第8段):


>操作数?应具有整数或枚举类型;
结果是其操作数的补充。进行整体促销活动。结果的类型是提升的
操作数的类型。 [...]



但也许是一个的补充表示类型将具有所有位反转的值,而不是反转二进制表示中所有

位的数学结果。例如,在32位
int的机器上,0的一个补码(尝试)的值是2 ^ 31-1,这是

不能用有符号的int表示,因此是未定义的,



呃...对不起,你能否详细说明,为什么(2 ^ 31-1)不能代表
代表?或者你的意思是(2 ^ 32 - 1)?


如果结果值大于''int''可以表示,

编译器将创建代码,首先将其提升为未签名,然后再将b $ blong推广到未签名长,即IIRC。所以,如果〜0因某种原因无法在一个int中表示

,它可能会成为(无符号){所有位设置}

值。
< blockquote class =post_quotes>
或者它是什么

具有所有设置位所具有的带符号int的值(-1

on two '补充机器)?



这就是我所期待的。


我使用了~0的情况简单;在实践中,这个问题可能会发生

当使用掩码的补码进行AND运算时,例如n& = ~0x0F清除

n的低4位,或者〜 n& 0x0F找到n的反相低4位。



实际上,在2'的补码上,我们使用-1代表所有位设置......

也许我们应切换到~0(更便携?)


V

-

请删除大写''A'当通过电子邮件回复

我没有回复最热门的回复,请不要问


10月20日,7日:51 * pm,blargg .... @ gishpuppy.com(blargg)写道:


是否~0会产生未定义的行为?



No.


C ++ 03第5节第5段似乎建议:


如果在评估表达式时,结果不是数学定义的b $ b其类型的可表示范围

值,行为未定义[...]


一元〜(C ++ 03第5.3.1节第8段)的描述:


的操作数?应具有整数或枚举类型;

结果是其操作数的补码。积分

促销活动。结果的类型是提升操作数的类型

。 [...]


但也许是一个的补充表示将所有位反转的类型的值,而不是反转二进制表示中所有位的数学结果。



对于没有使用

2'补码的机器而言,并不是很清楚会有什么期望,但最糟糕的是,它是未指定的或

实现定义---不是未定义的行为。 (一般来说,我会建议在签名类型上避免使用〜,|和& ;.


例如,在一台机器上32位int,是否一个'或
补0(尝试)的值为2 ^ 31-1,其中

不能表示为一个有符号的int,因此是未定义的,或者

它是否具有所有设置的带符号int的值

位将具有(-1表示两个'')补机)?



措辞有点草率,但无疑意味着

你得到一个值,所有位都设置为1(在指定的

类型)。当然,这个价值可能是依赖于实施的b $ b;它在2'的补码机器上为-1,

但在其他地方很容易为0。


我使用了~0为简单起见;在实践中,这个问题

可能在ANDing与掩码的补码时发生,对于

例子n& = ~0x0F来清除n的低4位,或者〜 n& 0x0F到

找到n的反相低4位。



只要符号位为0,行为应该很好定义,没有含糊之处。


-

James Kanze(GABI软件)电子邮件:ja ********* @ gmail.com

Conseils eninformatiqueorientée objet /

Beratung in objektorientierter Datenverarbeitung

9placeSémard,78210 St.-Cyr-l''coco,France,+ 33(0)1 30 23 00 34


在文章< gd ********** @ news.datemas.de> ;,, Victor Bazarov

< v 。******** @ comAcast.netwrote:


blargg写道:


~0产生未定义的行为? C ++ 03第5节第5段似乎

建议如此:


如果在评估表达式时,结果不是

在数学上定义或不在可表示的值范围内

的类型,行为未定义[...]



一元的描述〜(C ++ 03第5.3.1节第8段):


的操作数?应具有整数或枚举类型;

结果是其操作数的补码。整体促销

。结果的类型是提升的

操作数的类型。 [...]



但也许是一个的补充表示类型将具有所有位反转的值,而不是反转二进制表示中所有

位的数学结果。例如,在32位
int的机器上,0的一个补码(尝试)的值是2 ^ 31-1,这是

不能用有符号的int来表示,因此是未定义的,



呃...对不起,你能否详细说明,为什么(2 ^ 31-1)不能代表
代表?或者你的意思是(2 ^ 32 - 1)?



是的,(2 ^ 32 - 1);我发布之后就注意到了。


如果结果值大于''int''中可以表示的,那么

编译器将创建代码以将其首先推广为未签名,然后将b $ b长推广,然后创建为无签名长,IIRC。因此,如果〜0因某种原因无法在一个int中表示

,它可能会成为(无符号){所有位设置}

值。



不是我理解的,只有在选择

文字的类型时才会出现这种情况。如果你描述的是这种情况,那么

表达式的类型将取决于它的运行时值,例如,如果我是一个

int,那么表达式i + 1将是一个int,除非我包含

INT_MAX,其中它的类型为unsigned int。这显然不是

的情况,因为C ++是静态类型的。


或者它

具有所有设置位的带符号int的值(在两个补码机器上为-1

)?



这就是我所期待的。



问题是大多数编译器实现将值转换为

signed int作为无操作,即只是为了将这些位重新解释为

两个补码。


我使用了~0的情况为简单起见;在实践中,这个问题可能会发生

当使用掩码的补码进行AND运算时,例如n& = ~0x0F清除

n的低4位,或者〜 n& 0x0F找到n的反相低4位。



实际上,在2'的补码上,我们使用-1代表所有位设置...

也许我们应切换到~0(更便携?)



在我看来,0实际上不太便携。据我所知,

将-1转换为无符号类型保证给出一个设置了所有

位的值,因为该转换保证会给你两个即使机器

没有使用这样的表示(C ++ 03第4.7节第2段),无符号结果中的
补码表示。


Does ~0 yield undefined behavior? C++03 section 5 paragraph 5 seems to
suggest so:

If during the evaluation of an expression, the result is not
mathematically defined or not in the range of representable values
for its type, the behavior is undefined [...]

The description of unary ~ (C++03 section 5.3.1 paragraph 8):

The operand of ? shall have integral or enumeration type; the
result is the one''s complement of its operand. Integral promotions
are performed. The type of the result is the type of the promoted
operand. [...]

But perhaps "one''s complement" means the value that type would have with
all bits inverted, rather than the mathematical result of inverting all
bits in the binary representation. For example, on a machine with 32-bit
int, does one''s complement of 0 (attempt to) have the value 2^31-1, which
can''t be represented in a signed int and is thus undefined, or does it
have the value of whatever a signed int with all set bits would have (-1
on a two''s complement machine)?

I used the ~0 case for simplicity; in practice, this issue might occur
when ANDing with the complement of a mask, for example n&=~0x0F to clear
the low 4 bits of n, or ~n&0x0F to find the inverted low 4 bits of n.

解决方案

blargg wrote:

Does ~0 yield undefined behavior? C++03 section 5 paragraph 5 seems to
suggest so:

>If during the evaluation of an expression, the result is not
mathematically defined or not in the range of representable values
for its type, the behavior is undefined [...]


The description of unary ~ (C++03 section 5.3.1 paragraph 8):

>The operand of ? shall have integral or enumeration type; the
result is the one''s complement of its operand. Integral promotions
are performed. The type of the result is the type of the promoted
operand. [...]


But perhaps "one''s complement" means the value that type would have with
all bits inverted, rather than the mathematical result of inverting all
bits in the binary representation. For example, on a machine with 32-bit
int, does one''s complement of 0 (attempt to) have the value 2^31-1, which
can''t be represented in a signed int and is thus undefined,

Uh... Sorry, could you perhaps elaborate, why (2^31 - 1) can''t be
represented? Or did you mean (2^32 - 1)?

If the resulting value is greater than can be represented in ''int'', the
compiler will create the code to promote it first to ''unsigned'', then to
''long'', then to ''unsigned long'', IIRC. So, if ~0 cannot for some reason
be represented in an int, it might become the (unsigned){all bits set}
value.

or does it
have the value of whatever a signed int with all set bits would have (-1
on a two''s complement machine)?

That''s what I''d expect.

I used the ~0 case for simplicity; in practice, this issue might occur
when ANDing with the complement of a mask, for example n&=~0x0F to clear
the low 4 bits of n, or ~n&0x0F to find the inverted low 4 bits of n.

Actually, on 2''s complement, we use -1 for the "all bits set"...
Perhaps we should switch to ~0 (more portable?)

V
--
Please remove capital ''A''s when replying by e-mail
I do not respond to top-posted replies, please don''t ask


On Oct 20, 7:51*pm, blargg....@gishpuppy.com (blargg) wrote:

Does ~0 yield undefined behavior?

No.

C++03 section 5 paragraph 5 seems to suggest so:

If during the evaluation of an expression, the result is not
mathematically defined or not in the range of representable
values for its type, the behavior is undefined [...]

The description of unary ~ (C++03 section 5.3.1 paragraph 8):

The operand of ? shall have integral or enumeration type;
the result is the one''s complement of its operand. Integral
promotions are performed. The type of the result is the type
of the promoted operand. [...]

But perhaps "one''s complement" means the value that type would
have with all bits inverted, rather than the mathematical
result of inverting all bits in the binary representation.

It''s not really that clear what to expect on a machine not using
2''s complement, but at the worst, it''s unspecified or
implementation defined---not undefined behavior. (In general, I
would recommend avoiding ~, | and & on signed types.)

For example, on a machine with 32-bit int, does one''s
complement of 0 (attempt to) have the value 2^31-1, which
can''t be represented in a signed int and is thus undefined, or
does it have the value of whatever a signed int with all set
bits would have (-1 on a two''s complement machine)?

The wording is a bit sloppy, but what it doubtlessly means is
that you get a value with all bits set to one (in the specified
type). What that value is, of course, is probably
implementation dependent; it is -1 on a 2''s complement machine,
but could very easily be 0 elsewhere.

I used the ~0 case for simplicity; in practice, this issue
might occur when ANDing with the complement of a mask, for
example n&=~0x0F to clear the low 4 bits of n, or ~n&0x0F to
find the inverted low 4 bits of n.

As long as the sign bit is 0, the behavior should be well
defined, with no ambiguities.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l''école, France, +33 (0)1 30 23 00 34


In article <gd**********@news.datemas.de>, Victor Bazarov
<v.********@comAcast.netwrote:

blargg wrote:

Does ~0 yield undefined behavior? C++03 section 5 paragraph 5 seems to
suggest so:

If during the evaluation of an expression, the result is not
mathematically defined or not in the range of representable values
for its type, the behavior is undefined [...]

The description of unary ~ (C++03 section 5.3.1 paragraph 8):

The operand of ? shall have integral or enumeration type; the
result is the one''s complement of its operand. Integral promotions
are performed. The type of the result is the type of the promoted
operand. [...]

But perhaps "one''s complement" means the value that type would have with
all bits inverted, rather than the mathematical result of inverting all
bits in the binary representation. For example, on a machine with 32-bit
int, does one''s complement of 0 (attempt to) have the value 2^31-1, which
can''t be represented in a signed int and is thus undefined,


Uh... Sorry, could you perhaps elaborate, why (2^31 - 1) can''t be
represented? Or did you mean (2^32 - 1)?

Yeah, (2^32 - 1); I noticed just after I posted.

If the resulting value is greater than can be represented in ''int'', the
compiler will create the code to promote it first to ''unsigned'', then to
''long'', then to ''unsigned long'', IIRC. So, if ~0 cannot for some reason
be represented in an int, it might become the (unsigned){all bits set}
value.

Not as I understand it, where this only occurs when selecting what type a
literal will be. If what you described were the case, the type of an
expression would depend on its run-time value, for example if i were an
int, the type of the expression i+1 would be an int unless i contained
INT_MAX, where it would be of type unsigned int. This is clearly not the
case, since C++ is statically-typed.

or does it
have the value of whatever a signed int with all set bits would have (-1
on a two''s complement machine)?


That''s what I''d expect.

The problem is that most compilers implement conversion of a value to a
signed int as a no-op, that is, simply to reinterpret the bits as being in
two''s complement.

I used the ~0 case for simplicity; in practice, this issue might occur
when ANDing with the complement of a mask, for example n&=~0x0F to clear
the low 4 bits of n, or ~n&0x0F to find the inverted low 4 bits of n.


Actually, on 2''s complement, we use -1 for the "all bits set"...
Perhaps we should switch to ~0 (more portable?)

It seems to me that ~0 is actually less-portable. As far as I know,
converting -1 to an unsigned type is guaranteed to give a value with all
bits set, since that conversion is guaranteed to give you a two''s
complement representation in the unsigned result, even if the machine
doesn''t use such a representation (C++03 section 4.7 paragraph 2).


这篇关于~0 undefined?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆