请考虑以下代码:
vector<int> a = {1, 2, 3, 4, 5};
cout << a[-0] << std::endl;
此代码将编译并打印出1
。一切都很好。我假设编译器将-0
更改为0
。
有趣的问题:计算机中使用的数字系统是否允许-0
作为int
了?
我无法想到你需要int -0
的任何原因,这会使代码更加混乱?
是否有任何标志(如迂腐)会对此发出警告?
背景:我在一些工作代码中发现了一堆这些,不知道为什么,但我想确保将来知道它们。
答案 0 :(得分:6)
你正在向后看。事实上,在编译器中编写而不是的代码是无意义的,因为正如你所说的那样,表达式-0
完全有效,等同于0
。
您必须为一元-
引入一个新的特殊情况,应用于具有此特定值的整数文字......以及用于什么?
如果你正在编写令人困惑的代码,那么坦率地说这是你自己的错;编译器没有让你这样做。
答案 1 :(得分:2)
C ++允许对有符号整数进行3种不同的表示:2的补码,1的补码和有符号的整数。
-0
不是整数文字,它是一个表达式,由文字0
和应用了一元-
运算符组成。
在2的补码(几乎所有现代系统都使用)中,0
只有一个表示,因此-0
具有与0
完全相同的值和表示形式
在1的补码和有符号的幅度中,有一个明显的负零表示。 (通过反转1&amp;补码中的所有位,通过反转符号幅度的符号位,或通过反转所有位并在2的补码中加1来取反整数。在后一种情况下,应用这种对全零位表示的操作产生相同的表示。)
我认为将一元-
运算符应用于值0
是必需的,或者至少是预期的,以产生与0
相同的表示形式如果有负零的明确表示,但我无法通过快速扫描C ++标准来确认这一点。在非二进制补码系统中,可以创建一个保持负零表示的int
对象;这样的对象的值仍然应该等于0
。
在实践中,这不应引起关注;在2-s补充系统-0 == 0
上。
如果编译器为-0
发出警告,那将是因为-
没用,不是因为它不正确。
(了解为什么代码中存在-0
的情况会很有趣。)
答案 2 :(得分:1)
早期的编译通道之一可能会对常量项进行一些简化:例如,它可能会将int x = 0x100 | 0x001
转换为int x = 5
。在此过程中,负零可能会被简化。
在某些情况下警告-0
会增加编译器的复杂性,但收益很少。